HHH-13496 Pre-compile and reuse regular expressions

This commit is contained in:
Sanne Grinovero 2019-07-05 22:21:10 +01:00
parent bfc66ec356
commit 70d33e0c6b
8 changed files with 130 additions and 89 deletions

View File

@ -9,12 +9,21 @@ package org.hibernate.boot.model.source.internal.hbm;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.hibernate.internal.util.StringHelper;
/**
* @author Steve Ebersole
* @author Sanne Grinovero
*/
public class CommaSeparatedStringHelper {
public final class CommaSeparatedStringHelper {
private static final Pattern COMMA_SEPARATED_PATTERN = Pattern.compile( "\\s*,\\s*" );
private CommaSeparatedStringHelper() {
}
@ -22,21 +31,25 @@ public class CommaSeparatedStringHelper {
if ( values == null || values.isEmpty() ) {
return Collections.emptySet();
}
HashSet<String> set = new HashSet<String>();
Collections.addAll( set, values.split( "\\s*,\\s*" ) );
return set;
return COMMA_SEPARATED_PATTERN.splitAsStream( values ).collect( Collectors.toSet() );
}
public static Set<String> splitAndCombine(Set<String> x, String values) {
if ( x.isEmpty() && (values == null || values.isEmpty()) ) {
if ( x.isEmpty() && ( values == null || values.isEmpty() ) ) {
return Collections.emptySet();
}
HashSet<String> set = new HashSet<String>( x );
if ( values != null && !values.isEmpty() ) {
Collections.addAll( set, values.split( "\\s*,\\s*" ) );
Collections.addAll( set, COMMA_SEPARATED_PATTERN.split( values ) );
}
return set;
}
public static List<String> parseCommaSeparatedString(String incomingString) {
if ( StringHelper.isEmpty( incomingString ) ) {
return Collections.emptyList();
}
return COMMA_SEPARATED_PATTERN.splitAsStream( incomingString ).collect( Collectors.toList() );
}
}

View File

@ -6,6 +6,9 @@
*/
package org.hibernate.boot.model.source.spi;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.internal.util.StringHelper;
/**
@ -14,6 +17,11 @@ import org.hibernate.internal.util.StringHelper;
public abstract class AbstractAttributeKey {
// todo : replace this with "{element}"
private static final String COLLECTION_ELEMENT = "collection&&element";
private static final String DOT_COLLECTION_ELEMENT = '.' + COLLECTION_ELEMENT;
private static final Pattern DOT_COLLECTION_ELEMENT_PATTERN = Pattern.compile(
DOT_COLLECTION_ELEMENT,
Pattern.LITERAL
);
private final AbstractAttributeKey parent;
private final String property;
@ -130,11 +138,11 @@ public abstract class AbstractAttributeKey {
* marker ({@link #COLLECTION_ELEMENT}.
*/
public boolean isPartOfCollectionElement() {
return fullPath.contains( '.' + COLLECTION_ELEMENT );
return fullPath.contains( DOT_COLLECTION_ELEMENT );
}
public String stripCollectionElementMarker() {
return fullPath.replace( '.' + COLLECTION_ELEMENT, "" );
return DOT_COLLECTION_ELEMENT_PATTERN.matcher( fullPath ).replaceAll( Matcher.quoteReplacement( "" ) );
}
@Override

View File

@ -14,6 +14,7 @@ import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
@ -25,12 +26,17 @@ import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.MappingException;
import org.hibernate.NullPrecedence;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
@ -73,6 +79,7 @@ import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.persistent.PersistentTableBulkIdStrategy;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreLogging;
@ -96,6 +103,7 @@ import org.hibernate.sql.ANSIJoinFragment;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.ForUpdateFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
@ -107,6 +115,7 @@ import org.hibernate.tool.schema.internal.StandardTableExporter;
import org.hibernate.tool.schema.internal.StandardUniqueKeyExporter;
import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
@ -140,6 +149,11 @@ public abstract class Dialect implements ConversionContext {
* Characters used as closing for quoting SQL identifiers
*/
public static final String CLOSED_QUOTE = "`\"]";
private static final Pattern SINGLE_QUOTE_PATTERN = Pattern.compile(
"'",
Pattern.LITERAL
);
public static final String TWO_SINGLE_QUOTES_REPLACEMENT = Matcher.quoteReplacement( "''" );
private final TypeNames typeNames = new TypeNames();
private final TypeNames hibernateTypeNames = new TypeNames();
@ -325,9 +339,9 @@ public abstract class Dialect implements ConversionContext {
/**
* Get the name of the database type associated with the given
* {@link java.sql.Types} typecode.
* {@link Types} typecode.
*
* @param code The {@link java.sql.Types} typecode
* @param code The {@link Types} typecode
* @return the database type name
* @throws HibernateException If no mapping was specified for that type.
*/
@ -341,10 +355,10 @@ public abstract class Dialect implements ConversionContext {
/**
* Get the name of the database type associated with the given
* {@link java.sql.Types} typecode with the given storage specification
* {@link Types} typecode with the given storage specification
* parameters.
*
* @param code The {@link java.sql.Types} typecode
* @param code The {@link Types} typecode
* @param length The datatype length
* @param precision The datatype precision
* @param scale The datatype scale
@ -363,9 +377,9 @@ public abstract class Dialect implements ConversionContext {
/**
* Get the name of the database type appropriate for casting operations
* (via the CAST() SQL function) for the given {@link java.sql.Types} typecode.
* (via the CAST() SQL function) for the given {@link Types} typecode.
*
* @param code The {@link java.sql.Types} typecode
* @param code The {@link Types} typecode
* @return The database type name
*/
public String getCastTypeName(int code) {
@ -427,7 +441,7 @@ public abstract class Dialect implements ConversionContext {
* column length. <tt>$l</tt> in the type name with be replaced by the
* column length (if appropriate).
*
* @param code The {@link java.sql.Types} typecode
* @param code The {@link Types} typecode
* @param capacity The maximum length of database type
* @param name The database type name
*/
@ -439,7 +453,7 @@ public abstract class Dialect implements ConversionContext {
* Subclasses register a type name for the given type code. <tt>$l</tt> in
* the type name with be replaced by the column length (if appropriate).
*
* @param code The {@link java.sql.Types} typecode
* @param code The {@link Types} typecode
* @param name The database type name
*/
protected void registerColumnType(int code, String name) {
@ -450,7 +464,7 @@ public abstract class Dialect implements ConversionContext {
* Allows the dialect to override a {@link SqlTypeDescriptor}.
* <p/>
* If the passed {@code sqlTypeDescriptor} allows itself to be remapped (per
* {@link org.hibernate.type.descriptor.sql.SqlTypeDescriptor#canBeRemapped()}), then this method uses
* {@link SqlTypeDescriptor#canBeRemapped()}), then this method uses
* {@link #getSqlTypeDescriptorOverride} to get an optional override based on the SQL code returned by
* {@link SqlTypeDescriptor#getSqlType()}.
* <p/>
@ -648,11 +662,11 @@ public abstract class Dialect implements ConversionContext {
// hibernate type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Get the name of the Hibernate {@link org.hibernate.type.Type} associated with the given
* {@link java.sql.Types} type code.
* Get the name of the Hibernate {@link Type} associated with the given
* {@link Types} type code.
*
* @param code The {@link java.sql.Types} type code
* @return The Hibernate {@link org.hibernate.type.Type} name.
* @param code The {@link Types} type code
* @return The Hibernate {@link Type} name.
* @throws HibernateException If no mapping was specified for that type.
*/
@SuppressWarnings( {"UnusedDeclaration"})
@ -677,15 +691,15 @@ public abstract class Dialect implements ConversionContext {
}
/**
* Get the name of the Hibernate {@link org.hibernate.type.Type} associated
* with the given {@link java.sql.Types} typecode with the given storage
* Get the name of the Hibernate {@link Type} associated
* with the given {@link Types} typecode with the given storage
* specification parameters.
*
* @param code The {@link java.sql.Types} typecode
* @param code The {@link Types} typecode
* @param length The datatype length
* @param precision The datatype precision
* @param scale The datatype scale
* @return The Hibernate {@link org.hibernate.type.Type} name.
* @return The Hibernate {@link Type} name.
* @throws HibernateException If no mapping was specified for that type.
*/
public String getHibernateTypeName(int code, int length, int precision, int scale) throws HibernateException {
@ -703,23 +717,23 @@ public abstract class Dialect implements ConversionContext {
}
/**
* Registers a Hibernate {@link org.hibernate.type.Type} name for the given
* {@link java.sql.Types} type code and maximum column length.
* Registers a Hibernate {@link Type} name for the given
* {@link Types} type code and maximum column length.
*
* @param code The {@link java.sql.Types} typecode
* @param code The {@link Types} typecode
* @param capacity The maximum length of database type
* @param name The Hibernate {@link org.hibernate.type.Type} name
* @param name The Hibernate {@link Type} name
*/
protected void registerHibernateType(int code, long capacity, String name) {
hibernateTypeNames.put( code, capacity, name );
}
/**
* Registers a Hibernate {@link org.hibernate.type.Type} name for the given
* {@link java.sql.Types} type code.
* Registers a Hibernate {@link Type} name for the given
* {@link Types} type code.
*
* @param code The {@link java.sql.Types} typecode
* @param name The Hibernate {@link org.hibernate.type.Type} name
* @param code The {@link Types} typecode
* @param name The Hibernate {@link Type} name
*/
protected void registerHibernateType(int code, String name) {
hibernateTypeNames.put( code, name );
@ -736,7 +750,7 @@ public abstract class Dialect implements ConversionContext {
/**
* Retrieves a map of the dialect's registered functions
* (functionName => {@link org.hibernate.dialect.function.SQLFunction}).
* (functionName => {@link SQLFunction}).
*
* @return The map of registered functions.
*/
@ -748,7 +762,7 @@ public abstract class Dialect implements ConversionContext {
// native identifier generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* The class (which implements {@link org.hibernate.id.IdentifierGenerator})
* The class (which implements {@link IdentifierGenerator})
* which acts as this dialects native generation strategy.
* <p/>
* Comes into play whenever the user specifies the native generator.
@ -947,7 +961,7 @@ public abstract class Dialect implements ConversionContext {
* Get the select command used retrieve the names of all sequences.
*
* @return The select command; or null if sequences are not supported.
* @see org.hibernate.tool.hbm2ddl.SchemaUpdate
* @see SchemaUpdate
*/
public String getQuerySequencesString() {
return null;
@ -1129,8 +1143,8 @@ public abstract class Dialect implements ConversionContext {
*
* @param zeroBasedFirstResult The user-supplied, zero-based first row offset.
* @return The corresponding db/dialect specific offset.
* @see org.hibernate.Query#setFirstResult
* @see org.hibernate.Criteria#setFirstResult
* @see Query#setFirstResult
* @see Criteria#setFirstResult
* @deprecated {@link #getLimitHandler()} should be overridden instead.
*/
@Deprecated
@ -1156,7 +1170,7 @@ public abstract class Dialect implements ConversionContext {
* If this dialect supports specifying lock timeouts, are those timeouts
* rendered into the <tt>SQL</tt> string as parameters. The implication
* is that Hibernate will need to bind the timeout value as a parameter
* in the {@link java.sql.PreparedStatement}. If true, the param position
* in the {@link PreparedStatement}. If true, the param position
* is always handled as the last parameter; if the dialect specifies the
* lock timeout elsewhere in the <tt>SQL</tt> statement then the timeout
* value should be directly rendered into the statement and this method
@ -1498,7 +1512,7 @@ public abstract class Dialect implements ConversionContext {
/**
* Registers a parameter (either OUT, or the new REF_CURSOR param type available in Java 8) capable of
* returning {@link java.sql.ResultSet} *by position*. Pre-Java 8, registering such ResultSet-returning
* returning {@link ResultSet} *by position*. Pre-Java 8, registering such ResultSet-returning
* parameters varied greatly across database and drivers; hence its inclusion as part of the Dialect contract.
*
* @param statement The callable statement.
@ -1517,7 +1531,7 @@ public abstract class Dialect implements ConversionContext {
/**
* Registers a parameter (either OUT, or the new REF_CURSOR param type available in Java 8) capable of
* returning {@link java.sql.ResultSet} *by name*. Pre-Java 8, registering such ResultSet-returning
* returning {@link ResultSet} *by name*. Pre-Java 8, registering such ResultSet-returning
* parameters varied greatly across database and drivers; hence its inclusion as part of the Dialect contract.
*
* @param statement The callable statement.
@ -1537,7 +1551,7 @@ public abstract class Dialect implements ConversionContext {
/**
* Given a callable statement previously processed by {@link #registerResultSetOutParameter},
* extract the {@link java.sql.ResultSet} from the OUT parameter.
* extract the {@link ResultSet} from the OUT parameter.
*
* @param statement The callable statement.
* @return The extracted result set.
@ -1551,7 +1565,7 @@ public abstract class Dialect implements ConversionContext {
/**
* Given a callable statement previously processed by {@link #registerResultSetOutParameter},
* extract the {@link java.sql.ResultSet}.
* extract the {@link ResultSet}.
*
* @param statement The callable statement.
* @param position The bind position at which to register the output param.
@ -1569,7 +1583,7 @@ public abstract class Dialect implements ConversionContext {
/**
* Given a callable statement previously processed by {@link #registerResultSetOutParameter},
* extract the {@link java.sql.ResultSet} from the OUT parameter.
* extract the {@link ResultSet} from the OUT parameter.
*
* @param statement The callable statement.
* @param name The parameter name (for drivers which support named parameters).
@ -1711,14 +1725,14 @@ public abstract class Dialect implements ConversionContext {
// union subclass support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Given a {@link java.sql.Types} type code, determine an appropriate
* Given a {@link Types} type code, determine an appropriate
* null value to use in a select clause.
* <p/>
* One thing to consider here is that certain databases might
* require proper casting for the nulls here since the select here
* will be part of a UNION/UNION ALL.
*
* @param sqlType The {@link java.sql.Types} type code.
* @param sqlType The {@link Types} type code.
* @return The appropriate select clause value fragment.
*/
public String getSelectClauseNullString(int sqlType) {
@ -1740,21 +1754,21 @@ public abstract class Dialect implements ConversionContext {
/**
* Create a {@link org.hibernate.sql.JoinFragment} strategy responsible
* Create a {@link JoinFragment} strategy responsible
* for handling this dialect's variations in how joins are handled.
*
* @return This dialect's {@link org.hibernate.sql.JoinFragment} strategy.
* @return This dialect's {@link JoinFragment} strategy.
*/
public JoinFragment createOuterJoinFragment() {
return new ANSIJoinFragment();
}
/**
* Create a {@link org.hibernate.sql.CaseFragment} strategy responsible
* Create a {@link CaseFragment} strategy responsible
* for handling this dialect's variations in how CASE statements are
* handled.
*
* @return This dialect's {@link org.hibernate.sql.CaseFragment} strategy.
* @return This dialect's {@link CaseFragment} strategy.
*/
public CaseFragment createCaseFragment() {
return new ANSICaseFragment();
@ -1813,7 +1827,7 @@ public abstract class Dialect implements ConversionContext {
* to the database and perhaps manipulate them in some fashion.
* <p/>
* The recommend approach is to instead use
* {@link org.hibernate.Interceptor#onPrepareStatement(String)}.
* {@link Interceptor#onPrepareStatement(String)}.
*
* @param select The select command
* @return The mutated select command, or the same as was passed in.
@ -2052,7 +2066,7 @@ public abstract class Dialect implements ConversionContext {
* Get the SQL command used to retrieve the current schema name. Works in conjunction
* with {@link #getSchemaNameResolver()}, unless the return from there does not need this
* information. E.g., a custom impl might make use of the Java 1.7 addition of
* the {@link java.sql.Connection#getSchema()} method
* the {@link Connection#getSchema()} method
*
* @return The current schema retrieval SQL
*/
@ -2418,7 +2432,7 @@ public abstract class Dialect implements ConversionContext {
/**
* Should LOBs (both BLOB and CLOB) be bound using stream operations (i.e.
* {@link java.sql.PreparedStatement#setBinaryStream}).
* {@link PreparedStatement#setBinaryStream}).
*
* @return True if BLOBs and CLOBs should be bound using stream operations.
* @since 3.2
@ -2493,14 +2507,14 @@ public abstract class Dialect implements ConversionContext {
* Does this dialect support asking the result set its positioning
* information on forward only cursors. Specifically, in the case of
* scrolling fetches, Hibernate needs to use
* {@link java.sql.ResultSet#isAfterLast} and
* {@link java.sql.ResultSet#isBeforeFirst}. Certain drivers do not
* {@link ResultSet#isAfterLast} and
* {@link ResultSet#isBeforeFirst}. Certain drivers do not
* allow access to these methods for forward only cursors.
* <p/>
* NOTE : this is highly driver dependent!
*
* @return True if methods like {@link java.sql.ResultSet#isAfterLast} and
* {@link java.sql.ResultSet#isBeforeFirst} are supported for forward
* @return True if methods like {@link ResultSet#isAfterLast} and
* {@link ResultSet#isBeforeFirst} are supported for forward
* only cursors; false otherwise.
* @since 3.2
*/
@ -2559,17 +2573,17 @@ public abstract class Dialect implements ConversionContext {
* locator instance...
* <p/>
* For BLOBs, the internal value might be changed by:
* {@link java.sql.Blob#setBinaryStream},
* {@link java.sql.Blob#setBytes(long, byte[])},
* {@link java.sql.Blob#setBytes(long, byte[], int, int)},
* or {@link java.sql.Blob#truncate(long)}.
* {@link Blob#setBinaryStream},
* {@link Blob#setBytes(long, byte[])},
* {@link Blob#setBytes(long, byte[], int, int)},
* or {@link Blob#truncate(long)}.
* <p/>
* For CLOBs, the internal value might be changed by:
* {@link java.sql.Clob#setAsciiStream(long)},
* {@link java.sql.Clob#setCharacterStream(long)},
* {@link java.sql.Clob#setString(long, String)},
* {@link java.sql.Clob#setString(long, String, int, int)},
* or {@link java.sql.Clob#truncate(long)}.
* {@link Clob#setAsciiStream(long)},
* {@link Clob#setCharacterStream(long)},
* {@link Clob#setString(long, String)},
* {@link Clob#setString(long, String, int, int)},
* or {@link Clob#truncate(long)}.
* <p/>
* NOTE : I do not know the correct answer currently for
* databases which (1) are not part of the cruise control process
@ -2976,7 +2990,7 @@ public abstract class Dialect implements ConversionContext {
}
/**
* Check whether the JDBC {@link java.sql.Connection} supports creating LOBs via {@link Connection#createBlob()},
* Check whether the JDBC {@link Connection} supports creating LOBs via {@link Connection#createBlob()},
* {@link Connection#createNClob()} or {@link Connection#createClob()}.
*
* @param databaseMetaData JDBC {@link DatabaseMetaData} which can be used if LOB creation is supported only starting from a given Driver version
@ -2993,7 +3007,7 @@ public abstract class Dialect implements ConversionContext {
* @return escaped String
*/
protected String escapeLiteral(String literal) {
return literal.replace("'", "''");
return SINGLE_QUOTE_PATTERN.matcher( literal ).replaceAll( TWO_SINGLE_QUOTES_REPLACEMENT );
}
private void resolveLegacyLimitHandlerBehavior(ServiceRegistry serviceRegistry) {

View File

@ -10,6 +10,8 @@ import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.JDBCException;
import org.hibernate.NullPrecedence;
@ -45,6 +47,12 @@ import org.hibernate.type.StandardBasicTypes;
@SuppressWarnings("deprecation")
public class MySQLDialect extends Dialect {
private static final Pattern ESCAPE_PATTERN = Pattern.compile(
"\\",
Pattern.LITERAL
);
public static final String ESCAPE_PATTERN_REPLACEMENT = Matcher.quoteReplacement(
"\\\\" );
private final UniqueDelegate uniqueDelegate;
private final MySQLStorageEngine storageEngine;
@ -593,6 +601,6 @@ public class MySQLDialect extends Dialect {
@Override
protected String escapeLiteral(String literal) {
return super.escapeLiteral( literal ).replace("\\", "\\\\");
return ESCAPE_PATTERN.matcher( super.escapeLiteral( literal ) ).replaceAll( ESCAPE_PATTERN_REPLACEMENT );
}
}

View File

@ -16,6 +16,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.boot.model.source.internal.hbm.CommaSeparatedStringHelper;
import org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport;
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
@ -207,12 +208,7 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
}
private Set<String> parseKeywords(String extraKeywordsString) {
if ( StringHelper.isEmpty( extraKeywordsString ) ) {
return Collections.emptySet();
}
final Set<String> keywordSet = new HashSet<String>( Arrays.asList( extraKeywordsString.split( "\\s*,\\s*" ) ) );
return keywordSet;
return CommaSeparatedStringHelper.split( extraKeywordsString );
}
public Builder setConnectionSchemaName(String connectionSchemaName) {

View File

@ -63,10 +63,6 @@ public class IdentifierHelperBuilder {
}
private static List<String> parseKeywords(String extraKeywordsString) {
if ( StringHelper.isEmpty( extraKeywordsString ) ) {
return Collections.emptyList();
}
return StringHelper.parseCommaSeparatedString( extraKeywordsString );
}

View File

@ -20,6 +20,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.persistence.EntityGraph;
@ -108,7 +109,9 @@ import org.hibernate.persister.entity.Loadable;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.proxy.HibernateProxyHelper;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.spi.NamedQueryRepository;
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
import org.hibernate.resource.jdbc.spi.StatementInspector;
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.AfterCompletionAction;
@ -155,6 +158,7 @@ import static org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting.det
*/
public final class SessionFactoryImpl implements SessionFactoryImplementor {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SessionFactoryImpl.class );
private static final Pattern LISTENER_SEPARATION_PATTERN = Pattern.compile( " ," );
private final String name;
private final String uuid;
@ -178,7 +182,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
private final transient CriteriaBuilderImpl criteriaBuilder;
private final PersistenceUnitUtil jpaPersistenceUnitUtil;
private final transient CacheImplementor cacheAccess;
private final transient org.hibernate.query.spi.NamedQueryRepository namedQueryRepository;
private final transient NamedQueryRepository namedQueryRepository;
private final transient QueryPlanCache queryPlanCache;
private final transient CurrentSessionContext currentSessionContext;
@ -410,7 +414,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
);
final EventType eventType = EventType.resolveEventTypeByName( eventTypeName );
final EventListenerGroup eventListenerGroup = eventListenerRegistry.getEventListenerGroup( eventType );
for ( String listenerImpl : ( (String) entry.getValue() ).split( " ," ) ) {
for ( String listenerImpl : LISTENER_SEPARATION_PATTERN.split( ( (String) entry.getValue() ) ) ) {
eventListenerGroup.appendListener( instantiate( listenerImpl, classLoaderService ) );
}
}
@ -712,7 +716,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
}
@Override
public org.hibernate.query.spi.NamedQueryRepository getNamedQueryRepository() {
public NamedQueryRepository getNamedQueryRepository() {
return namedQueryRepository;
}
@ -863,10 +867,10 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
org.hibernate.query.Query hibernateQuery = query.unwrap( org.hibernate.query.Query.class );
if ( hibernateQuery != null ) {
// create and register the proper NamedQueryDefinition...
if ( org.hibernate.query.NativeQuery.class.isInstance( hibernateQuery ) ) {
if ( NativeQuery.class.isInstance( hibernateQuery ) ) {
getNamedQueryRepository().registerNamedSQLQueryDefinition(
name,
extractSqlQueryDefinition( (org.hibernate.query.NativeQuery) hibernateQuery, name )
extractSqlQueryDefinition( (NativeQuery) hibernateQuery, name )
);
}
else {
@ -898,7 +902,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
);
}
private NamedSQLQueryDefinition extractSqlQueryDefinition(org.hibernate.query.NativeQuery nativeSqlQuery, String name) {
private NamedSQLQueryDefinition extractSqlQueryDefinition(NativeQuery nativeSqlQuery, String name) {
final NamedSQLQueryDefinitionBuilder builder = new NamedSQLQueryDefinitionBuilder( name );
fillInNamedQueryBuilder( builder, nativeSqlQuery );
builder.setCallable( nativeSqlQuery.isCallable() )

View File

@ -15,7 +15,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import org.hibernate.boot.model.source.internal.hbm.CommaSeparatedStringHelper;
import org.hibernate.dialect.Dialect;
import org.hibernate.internal.util.collections.ArrayHelper;
@ -700,8 +702,8 @@ public final class StringHelper {
* Determine if the given name is quoted. It is considered quoted if either:
* <ol>
* <li>starts AND ends with backticks (`)</li>
* <li>starts with dialect-specified {@link org.hibernate.dialect.Dialect#openQuote() open-quote}
* AND ends with dialect-specified {@link org.hibernate.dialect.Dialect#closeQuote() close-quote}</li>
* <li>starts with dialect-specified {@link Dialect#openQuote() open-quote}
* AND ends with dialect-specified {@link Dialect#closeQuote() close-quote}</li>
* </ol>
*
* @param name The name to check
@ -835,7 +837,7 @@ public final class StringHelper {
}
public static List<String> parseCommaSeparatedString(String incomingString) {
return Arrays.asList( incomingString.split( "\\s*,\\s*" ) );
return CommaSeparatedStringHelper.parseCommaSeparatedString( incomingString );
}
public static <T> String join(Collection<T> values, Renderer<T> renderer) {