Created
February 23, 2012 03:07
-
-
Save stliu/1889714 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/build.gradle b/build.gradle | |
index 73116a5..b16924c 100644 | |
--- a/build.gradle | |
+++ b/build.gradle | |
@@ -64,8 +64,9 @@ libraries = [ | |
classmate: 'com.fasterxml:classmate:0.5.4', | |
// Jakarta commons-collections todo : get rid of commons-collections dependency | |
- commons_collections: | |
- 'commons-collections:commons-collections:3.2.1', | |
+// commons_collections: | |
+// 'commons-collections:commons-collections:3.2.1', | |
+ guava: 'com.google.guava:guava:11.0.1@jar', | |
// Dom4J | |
dom4j: 'dom4j:dom4j:1.6.1@jar', | |
diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle | |
index 99a98e8..6c6b0cb 100644 | |
--- a/hibernate-core/hibernate-core.gradle | |
+++ b/hibernate-core/hibernate-core.gradle | |
@@ -4,7 +4,7 @@ apply plugin: org.hibernate.build.gradle.inject.InjectionPlugin | |
apply plugin: org.hibernate.build.gradle.testing.matrix.MatrixTestingPlugin | |
dependencies { | |
- compile( libraries.commons_collections ) | |
+ compile( libraries.guava ) | |
compile( libraries.jta ) | |
compile( libraries.dom4j ) { | |
transitive = false | |
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java | |
index c6ae439..399f251 100644 | |
--- a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java | |
+++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java | |
@@ -39,8 +39,7 @@ import java.util.Map; | |
import java.util.Map.Entry; | |
import java.util.concurrent.ConcurrentHashMap; | |
-import org.apache.commons.collections.map.AbstractReferenceMap; | |
-import org.apache.commons.collections.map.ReferenceMap; | |
+import com.google.common.collect.MapMaker; | |
import org.hibernate.AssertionFailure; | |
import org.hibernate.Hibernate; | |
import org.hibernate.HibernateException; | |
@@ -164,7 +163,8 @@ public class StatefulPersistenceContext implements PersistenceContext { | |
entitiesByKey = new HashMap<EntityKey, Object>( INIT_COLL_SIZE ); | |
entitiesByUniqueKey = new HashMap<EntityUniqueKey, Object>( INIT_COLL_SIZE ); | |
//noinspection unchecked | |
- proxiesByKey = (Map<EntityKey, Object>) new ReferenceMap( AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK ); | |
+ proxiesByKey = | |
+ new MapMaker().concurrencyLevel( 1 ).weakValues().initialCapacity( INIT_COLL_SIZE ).<EntityKey, Object>makeMap(); | |
entitySnapshotsByKey = new HashMap<EntityKey, Object>( INIT_COLL_SIZE ); | |
entityEntries = IdentityMap.instantiateSequenced( INIT_COLL_SIZE ); | |
@@ -1580,7 +1580,8 @@ public class StatefulPersistenceContext implements PersistenceContext { | |
count = ois.readInt(); | |
if ( tracing ) LOG.trace("Starting deserialization of [" + count + "] proxiesByKey entries"); | |
//noinspection unchecked | |
- rtn.proxiesByKey = new ReferenceMap( AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK, count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count, .75f ); | |
+// rtn.proxiesByKey = new ReferenceMap( AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK, count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count, .75f ); | |
+ rtn.proxiesByKey = new MapMaker().concurrencyLevel( 1 ).weakValues().initialCapacity( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count ).<EntityKey, Object>makeMap(); | |
for ( int i = 0; i < count; i++ ) { | |
EntityKey ek = EntityKey.deserialize( ois, session ); | |
Object proxy = ois.readObject(); | |
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java | |
index 805c8ab..27608bc 100644 | |
--- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java | |
+++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java | |
@@ -32,6 +32,7 @@ import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
+import com.google.common.collect.ImmutableSet; | |
import org.jboss.logging.Logger; | |
import org.hibernate.HibernateException; | |
@@ -46,6 +47,7 @@ import org.hibernate.hql.internal.QuerySplitter; | |
import org.hibernate.hql.spi.FilterTranslator; | |
import org.hibernate.hql.spi.ParameterTranslations; | |
import org.hibernate.hql.spi.QueryTranslator; | |
+import org.hibernate.hql.spi.QueryTranslatorFactory; | |
import org.hibernate.internal.CoreMessageLogger; | |
import org.hibernate.internal.util.collections.ArrayHelper; | |
import org.hibernate.internal.util.collections.EmptyIterator; | |
@@ -84,27 +86,30 @@ public class HQLQueryPlan implements Serializable { | |
this.sourceQuery = hql; | |
this.shallow = shallow; | |
- Set copy = new HashSet(); | |
- copy.addAll( enabledFilters.keySet() ); | |
- this.enabledFilterNames = java.util.Collections.unmodifiableSet( copy ); | |
+ this.enabledFilterNames = ImmutableSet.copyOf( enabledFilters.keySet() ); | |
- Set combinedQuerySpaces = new HashSet(); | |
- String[] concreteQueryStrings = QuerySplitter.concreteQueries( hql, factory ); | |
+ | |
+ final String[] concreteQueryStrings = QuerySplitter.concreteQueries( hql, factory ); | |
final int length = concreteQueryStrings.length; | |
- translators = new QueryTranslator[length]; | |
+ this.translators = new QueryTranslator[length]; | |
+ | |
List sqlStringList = new ArrayList(); | |
+ Set combinedQuerySpaces = new HashSet(); | |
+ | |
+ final boolean hasCollectionRole = (collectionRole == null); | |
+ final Map querySubstitutions = factory.getSettings().getQuerySubstitutions(); | |
+ final QueryTranslatorFactory queryTranslatorFactory = factory.getSettings().getQueryTranslatorFactory(); | |
+ | |
for ( int i=0; i<length; i++ ) { | |
- if ( collectionRole == null ) { | |
- translators[i] = factory.getSettings() | |
- .getQueryTranslatorFactory() | |
+ if ( hasCollectionRole ) { | |
+ translators[i] = queryTranslatorFactory | |
.createQueryTranslator( hql, concreteQueryStrings[i], enabledFilters, factory ); | |
- translators[i].compile( factory.getSettings().getQuerySubstitutions(), shallow ); | |
+ translators[i].compile( querySubstitutions, shallow ); | |
} | |
else { | |
- translators[i] = factory.getSettings() | |
- .getQueryTranslatorFactory() | |
+ translators[i] = queryTranslatorFactory | |
.createFilterTranslator( hql, concreteQueryStrings[i], enabledFilters, factory ); | |
- ( ( FilterTranslator ) translators[i] ).compile( collectionRole, factory.getSettings().getQuerySubstitutions(), shallow ); | |
+ ( ( FilterTranslator ) translators[i] ).compile( collectionRole, querySubstitutions, shallow ); | |
} | |
combinedQuerySpaces.addAll( translators[i].getQuerySpaces() ); | |
sqlStringList.addAll( translators[i].collectSqlStrings() ); | |
@@ -123,13 +128,8 @@ public class HQLQueryPlan implements Serializable { | |
returnMetadata = null; | |
} | |
else { | |
- if ( length > 1 ) { | |
- final int returns = translators[0].getReturnTypes().length; | |
- returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), new Type[returns] ); | |
- } | |
- else { | |
- returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), translators[0].getReturnTypes() ); | |
- } | |
+ final Type[] types = ( length > 1 ) ? new Type[translators[0].getReturnTypes().length] : translators[0].getReturnTypes(); | |
+ returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), types ); | |
} | |
} | |
} | |
@@ -239,14 +239,16 @@ public class HQLQueryPlan implements Serializable { | |
Iterator[] results = null; | |
boolean many = translators.length > 1; | |
- if (many) { | |
+ if ( many ) { | |
results = new Iterator[translators.length]; | |
} | |
Iterator result = null; | |
for ( int i = 0; i < translators.length; i++ ) { | |
result = translators[i].iterate( queryParameters, session ); | |
- if (many) results[i] = result; | |
+ if ( many ) { | |
+ results[i] = result; | |
+ } | |
} | |
return many ? new JoinedIterator(results) : result; | |
@@ -289,7 +291,9 @@ public class HQLQueryPlan implements Serializable { | |
long start = System.currentTimeMillis(); | |
ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( hql ); | |
long end = System.currentTimeMillis(); | |
- LOG.tracev( "HQL param location recognition took {0} mills ({1})", ( end - start ), hql ); | |
+ if ( LOG.isTraceEnabled() ) { | |
+ LOG.tracev( "HQL param location recognition took {0} mills ({1})", ( end - start ), hql ); | |
+ } | |
int ordinalParamCount = parameterTranslations.getOrdinalParameterCount(); | |
int[] locations = ArrayHelper.toIntArray( recognizer.getOrdinalParameterLocationList() ); | |
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java | |
index 6588970..34cb461 100644 | |
--- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java | |
+++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java | |
@@ -31,9 +31,18 @@ import java.util.HashSet; | |
import java.util.Iterator; | |
import java.util.Map; | |
import java.util.Set; | |
- | |
+import java.util.concurrent.ConcurrentMap; | |
+import java.util.concurrent.ExecutionException; | |
+ | |
+import com.google.common.cache.CacheBuilder; | |
+import com.google.common.cache.CacheLoader; | |
+import com.google.common.cache.LoadingCache; | |
+import com.google.common.cache.RemovalListener; | |
+import com.google.common.cache.RemovalNotification; | |
+import com.google.common.collect.ImmutableSet; | |
import org.jboss.logging.Logger; | |
+import org.hibernate.HibernateException; | |
import org.hibernate.MappingException; | |
import org.hibernate.QueryException; | |
import org.hibernate.cfg.Environment; | |
@@ -42,7 +51,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; | |
import org.hibernate.internal.CoreMessageLogger; | |
import org.hibernate.internal.FilterImpl; | |
import org.hibernate.internal.util.collections.CollectionHelper; | |
-import org.hibernate.internal.util.collections.SimpleMRUCache; | |
import org.hibernate.internal.util.collections.SoftLimitMRUCache; | |
import org.hibernate.internal.util.config.ConfigurationHelper; | |
@@ -57,23 +65,17 @@ import org.hibernate.internal.util.config.ConfigurationHelper; | |
public class QueryPlanCache implements Serializable { | |
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, QueryPlanCache.class.getName()); | |
- /** | |
- * simple cache of param metadata based on query string. Ideally, the original "user-supplied query" | |
- * string should be used to obtain this metadata (i.e., not the para-list-expanded query string) to avoid | |
- * unnecessary cache entries. | |
- * <p> | |
- * Used solely for caching param metadata for native-sql queries, see {@link #getSQLParameterMetadata} for a | |
- * discussion as to why... | |
- */ | |
- private final SimpleMRUCache sqlParamMetadataCache; | |
- | |
- /** | |
- * the cache of the actual plans... | |
- */ | |
- private final SoftLimitMRUCache planCache; | |
- private SessionFactoryImplementor factory; | |
- | |
- public QueryPlanCache(SessionFactoryImplementor factory) { | |
+ private final SessionFactoryImplementor factory; | |
+ private final ConcurrentMap softReferenceMap; | |
+ private final LoadingCache<String, ParameterMetadata> sqlParameterMetadataCache; | |
+ private final LoadingCache<HQLQueryPlanKey, HQLQueryPlan> hqlQueryPlanCache; | |
+ private final LoadingCache<NativeSQLQuerySpecification, NativeSQLQueryPlan> nativeQueryPlanCache; | |
+ private final LoadingCache<FilterQueryPlanKey, FilterQueryPlan> filterQueryPlanCache; | |
+ private final CacheRemovalListener removalListener; | |
+ | |
+ public QueryPlanCache(final SessionFactoryImplementor factory) { | |
+ this.factory = factory; | |
+ | |
int maxStrongReferenceCount = ConfigurationHelper.getInt( | |
Environment.QUERY_PLAN_CACHE_MAX_STRONG_REFERENCES, | |
factory.getProperties(), | |
@@ -84,10 +86,32 @@ public class QueryPlanCache implements Serializable { | |
factory.getProperties(), | |
SoftLimitMRUCache.DEFAULT_SOFT_REF_COUNT | |
); | |
- | |
- this.factory = factory; | |
- this.sqlParamMetadataCache = new SimpleMRUCache( maxStrongReferenceCount ); | |
- this.planCache = new SoftLimitMRUCache( maxStrongReferenceCount, maxSoftReferenceCount ); | |
+ this.softReferenceMap = CacheBuilder.newBuilder() | |
+ .maximumSize( maxSoftReferenceCount ) | |
+ .softValues() | |
+ .concurrencyLevel( 16 ) | |
+ .build().asMap(); | |
+ this.removalListener = new CacheRemovalListener( softReferenceMap ); | |
+ | |
+ this.hqlQueryPlanCache = CacheBuilder.newBuilder() | |
+ .maximumSize( maxStrongReferenceCount ) | |
+ .concurrencyLevel( 16 ) | |
+ .removalListener( removalListener ) | |
+ .build( new HQLQueryPlanCacheLoader() ); | |
+ this.filterQueryPlanCache = CacheBuilder.newBuilder() | |
+ .maximumSize( maxStrongReferenceCount ) | |
+ .concurrencyLevel( 16 ) | |
+ .removalListener( removalListener ) | |
+ .build( new FilterQueryPlanCacheLoader() ); | |
+ this.nativeQueryPlanCache = CacheBuilder.newBuilder() | |
+ .maximumSize( maxStrongReferenceCount ) | |
+ .removalListener( removalListener ) | |
+ .concurrencyLevel( 16 ) | |
+ .build( new NativeSQLQueryPlanCacheLoader() ); | |
+ this.sqlParameterMetadataCache = CacheBuilder.newBuilder() | |
+ .maximumSize( maxStrongReferenceCount ) | |
+ .concurrencyLevel( 16 ) | |
+ .build( new SqlParameterMetadataCacheLoader() ); | |
} | |
/** | |
@@ -100,95 +124,158 @@ public class QueryPlanCache implements Serializable { | |
* @param query The query | |
* @return The parameter metadata | |
*/ | |
- public ParameterMetadata getSQLParameterMetadata(String query) { | |
- ParameterMetadata metadata = ( ParameterMetadata ) sqlParamMetadataCache.get( query ); | |
- if ( metadata == null ) { | |
- metadata = buildNativeSQLParameterMetadata( query ); | |
- sqlParamMetadataCache.put( query, metadata ); | |
- } | |
- return metadata; | |
+ public ParameterMetadata getSQLParameterMetadata(final String query) { | |
+ return sqlParameterMetadataCache.getUnchecked( query ); | |
} | |
- public HQLQueryPlan getHQLQueryPlan(String queryString, boolean shallow, Map enabledFilters) | |
+ public HQLQueryPlan getHQLQueryPlan( String queryString, boolean shallow, Map enabledFilters) | |
throws QueryException, MappingException { | |
- HQLQueryPlanKey key = new HQLQueryPlanKey( queryString, shallow, enabledFilters ); | |
- HQLQueryPlan plan = ( HQLQueryPlan ) planCache.get ( key ); | |
- | |
- if ( plan == null ) { | |
- LOG.tracev( "Unable to locate HQL query plan in cache; generating ({0})", queryString ); | |
- plan = new HQLQueryPlan(queryString, shallow, enabledFilters, factory ); | |
+ try { | |
+ return hqlQueryPlanCache.get( new HQLQueryPlanKey( queryString, shallow, enabledFilters ) ); | |
} | |
- else { | |
- LOG.tracev( "Located HQL query plan in cache ({0})", queryString ); | |
+ catch ( ExecutionException e ) { | |
+ handleExecutionExcetpion( e ); | |
} | |
- planCache.put( key, plan ); | |
- | |
- return plan; | |
+ throw new HibernateException( "will never reach here" ); | |
} | |
+ | |
+ | |
public FilterQueryPlan getFilterQueryPlan(String filterString, String collectionRole, boolean shallow, Map enabledFilters) | |
throws QueryException, MappingException { | |
- FilterQueryPlanKey key = new FilterQueryPlanKey( filterString, collectionRole, shallow, enabledFilters ); | |
- FilterQueryPlan plan = ( FilterQueryPlan ) planCache.get ( key ); | |
+ try { | |
+ return filterQueryPlanCache.get( new FilterQueryPlanKey( filterString, collectionRole, shallow, enabledFilters ) ); | |
+ } | |
+ catch ( ExecutionException e ) { | |
+ handleExecutionExcetpion(e); | |
+ } | |
+ throw new HibernateException( "will never reach here" ); | |
+ } | |
- if ( plan == null ) { | |
- LOG.tracev( "Unable to locate collection-filter query plan in cache; generating ({0} : {1} )", | |
- collectionRole, filterString ); | |
- plan = new FilterQueryPlan( filterString, collectionRole, shallow, enabledFilters, factory ); | |
+ private void handleExecutionExcetpion(ExecutionException e){ | |
+ Throwable cause = e.getCause(); | |
+ if ( cause == null ) { | |
+ throw new HibernateException( e ); | |
+ } | |
+ else if ( cause instanceof QueryException ) { | |
+ throw (QueryException) cause; | |
+ } | |
+ else if ( cause instanceof MappingException ) { | |
+ throw (MappingException) cause; | |
} | |
else { | |
- LOG.tracev( "Located collection-filter query plan in cache ({0} : {1})", collectionRole, filterString ); | |
+ throw new HibernateException( e ); | |
} | |
+ } | |
- planCache.put( key, plan ); | |
+ public NativeSQLQueryPlan getNativeSQLQueryPlan(final NativeSQLQuerySpecification spec) { | |
+ return nativeQueryPlanCache.getUnchecked( spec ); | |
+ } | |
- return plan; | |
+ //clean up QueryPlanCache when Sessionfactory is closed | |
+ public void destroy() { | |
+ sqlParameterMetadataCache.cleanUp(); | |
+ softReferenceMap.clear(); | |
+ hqlQueryPlanCache.cleanUp(); | |
+ nativeQueryPlanCache.cleanUp(); | |
+ sqlParameterMetadataCache.cleanUp(); | |
} | |
- public NativeSQLQueryPlan getNativeSQLQueryPlan(NativeSQLQuerySpecification spec) { | |
- NativeSQLQueryPlan plan = ( NativeSQLQueryPlan ) planCache.get( spec ); | |
+ private class CacheRemovalListener implements RemovalListener { | |
+ private final ConcurrentMap cache; | |
+ | |
+ private CacheRemovalListener(ConcurrentMap cache) { | |
+ this.cache = cache; | |
+ } | |
- if ( plan == null ) { | |
- if ( LOG.isTraceEnabled() ) { | |
- LOG.tracev( "Unable to locate native-sql query plan in cache; generating ({0})", spec.getQueryString() ); | |
+ @Override | |
+ public void onRemoval(RemovalNotification removalNotification) { | |
+ Object key = removalNotification.getKey(); | |
+ Object value = removalNotification.getValue(); | |
+ cache.put( key, value ); | |
+ } | |
+ } | |
+ | |
+ private class NativeSQLQueryPlanCacheLoader extends CacheLoader<NativeSQLQuerySpecification, NativeSQLQueryPlan>{ | |
+ @Override | |
+ public NativeSQLQueryPlan load(NativeSQLQuerySpecification key) throws Exception { | |
+ NativeSQLQueryPlan nativeSQLQueryPlan = (NativeSQLQueryPlan) QueryPlanCache.this.softReferenceMap | |
+ .remove( key ); | |
+ return nativeSQLQueryPlan != null ? nativeSQLQueryPlan : new NativeSQLQueryPlan( | |
+ key, | |
+ QueryPlanCache.this.factory | |
+ ); | |
+ } | |
+ } | |
+ | |
+ private class FilterQueryPlanCacheLoader extends CacheLoader<FilterQueryPlanKey, FilterQueryPlan>{ | |
+ @Override | |
+ public FilterQueryPlan load(FilterQueryPlanKey key) throws Exception { | |
+ FilterQueryPlan filterQueryPlan = (FilterQueryPlan) QueryPlanCache.this.softReferenceMap.remove( key ); | |
+ if ( filterQueryPlan == null ) { | |
+ if ( LOG.isTraceEnabled() ) { | |
+ LOG.tracev( | |
+ "Unable to locate collection-filter query plan in cache; generating ({0} : {1} )", | |
+ key.collectionRole, | |
+ key.query | |
+ ); | |
+ } | |
+ filterQueryPlan = new FilterQueryPlan( | |
+ key.query, | |
+ key.collectionRole, | |
+ key.shallow, | |
+ key.enabledFilters, | |
+ QueryPlanCache.this.factory | |
+ ); | |
} | |
- plan = new NativeSQLQueryPlan( spec, factory ); | |
+ return filterQueryPlan; | |
} | |
- else { | |
- if ( LOG.isTraceEnabled() ) { | |
- LOG.tracev( "Located native-sql query plan in cache ({0})", spec.getQueryString() ); | |
+ } | |
+ private class HQLQueryPlanCacheLoader extends CacheLoader<HQLQueryPlanKey, HQLQueryPlan>{ | |
+ @Override | |
+ public HQLQueryPlan load(HQLQueryPlanKey key) throws Exception { | |
+ HQLQueryPlan hqlQueryPlan = (HQLQueryPlan) QueryPlanCache.this.softReferenceMap.remove( key ); | |
+ if ( hqlQueryPlan == null ) { | |
+ if ( LOG.isTraceEnabled() ) { | |
+ LOG.tracev( "Unable to locate HQL query plan in cache; generating ({0})", key.query ); | |
+ } | |
+ hqlQueryPlan = new HQLQueryPlan( | |
+ key.query, | |
+ key.shallow, | |
+ key.enabledFilters, | |
+ QueryPlanCache.this.factory | |
+ ); | |
} | |
+ return hqlQueryPlan; | |
} | |
- | |
- planCache.put( spec, plan ); | |
- return plan; | |
} | |
- @SuppressWarnings({ "UnnecessaryUnboxing" }) | |
- private ParameterMetadata buildNativeSQLParameterMetadata(String sqlString) { | |
- ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( sqlString ); | |
+ private static class SqlParameterMetadataCacheLoader extends CacheLoader<String, ParameterMetadata>{ | |
+ @Override | |
+ public ParameterMetadata load(String sqlString) { | |
+ ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( sqlString ); | |
+ final int size = recognizer.getOrdinalParameterLocationList().size(); | |
+ OrdinalParameterDescriptor[] ordinalDescriptors = new OrdinalParameterDescriptor[ size ]; | |
+ for ( int i = 0; i < size; i++ ) { | |
+ final Integer position = ( Integer ) recognizer.getOrdinalParameterLocationList().get( i ); | |
+ ordinalDescriptors[i] = new OrdinalParameterDescriptor( i, null, position ); | |
+ } | |
- OrdinalParameterDescriptor[] ordinalDescriptors = | |
- new OrdinalParameterDescriptor[ recognizer.getOrdinalParameterLocationList().size() ]; | |
- for ( int i = 0; i < recognizer.getOrdinalParameterLocationList().size(); i++ ) { | |
- final Integer position = ( Integer ) recognizer.getOrdinalParameterLocationList().get( i ); | |
- ordinalDescriptors[i] = new OrdinalParameterDescriptor( i, null, position.intValue() ); | |
- } | |
+ Iterator itr = recognizer.getNamedParameterDescriptionMap().entrySet().iterator(); | |
+ Map<String,NamedParameterDescriptor> namedParamDescriptorMap = new HashMap<String,NamedParameterDescriptor>(); | |
+ while( itr.hasNext() ) { | |
+ final Map.Entry entry = ( Map.Entry ) itr.next(); | |
+ final String name = ( String ) entry.getKey(); | |
+ final ParamLocationRecognizer.NamedParameterDescription description = | |
+ ( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue(); | |
+ namedParamDescriptorMap.put( | |
+ name , | |
+ new NamedParameterDescriptor( name, null, description.buildPositionsArray(), description.isJpaStyle() ) | |
+ ); | |
+ } | |
- Iterator itr = recognizer.getNamedParameterDescriptionMap().entrySet().iterator(); | |
- Map<String,NamedParameterDescriptor> namedParamDescriptorMap = new HashMap<String,NamedParameterDescriptor>(); | |
- while( itr.hasNext() ) { | |
- final Map.Entry entry = ( Map.Entry ) itr.next(); | |
- final String name = ( String ) entry.getKey(); | |
- final ParamLocationRecognizer.NamedParameterDescription description = | |
- ( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue(); | |
- namedParamDescriptorMap.put( | |
- name , | |
- new NamedParameterDescriptor( name, null, description.buildPositionsArray(), description.isJpaStyle() ) | |
- ); | |
+ return new ParameterMetadata( ordinalDescriptors, namedParamDescriptorMap ); | |
} | |
- | |
- return new ParameterMetadata( ordinalDescriptors, namedParamDescriptorMap ); | |
} | |
private static class HQLQueryPlanKey implements Serializable { | |
@@ -196,12 +283,13 @@ public class QueryPlanCache implements Serializable { | |
private final boolean shallow; | |
private final Set<DynamicFilterKey> filterKeys; | |
private final int hashCode; | |
+ private final transient Map enabledFilters; | |
public HQLQueryPlanKey(String query, boolean shallow, Map enabledFilters) { | |
this.query = query; | |
this.shallow = shallow; | |
- | |
- if ( enabledFilters == null || enabledFilters.isEmpty() ) { | |
+ this.enabledFilters = enabledFilters; | |
+ if ( CollectionHelper.isEmpty( enabledFilters ) ) { | |
filterKeys = Collections.emptySet(); | |
} | |
else { | |
@@ -307,20 +395,20 @@ public class QueryPlanCache implements Serializable { | |
private final boolean shallow; | |
private final Set<String> filterNames; | |
private final int hashCode; | |
+ private final transient Map enabledFilters; | |
@SuppressWarnings({ "unchecked" }) | |
public FilterQueryPlanKey(String query, String collectionRole, boolean shallow, Map enabledFilters) { | |
this.query = query; | |
this.collectionRole = collectionRole; | |
this.shallow = shallow; | |
+ this.enabledFilters = enabledFilters; | |
- if ( enabledFilters == null || enabledFilters.isEmpty() ) { | |
- filterNames = Collections.emptySet(); | |
+ if ( CollectionHelper.isEmpty( enabledFilters ) ) { | |
+ this.filterNames = Collections.emptySet(); | |
} | |
else { | |
- Set<String> tmp = new HashSet<String>(); | |
- tmp.addAll( enabledFilters.keySet() ); | |
- this.filterNames = Collections.unmodifiableSet( tmp ); | |
+ this.filterNames = ImmutableSet.<String>copyOf( enabledFilters.keySet() );; | |
} | |
int hash = query.hashCode(); | |
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java | |
index 7d32b78..cf2f29d 100755 | |
--- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java | |
+++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java | |
@@ -42,6 +42,7 @@ import org.hibernate.engine.jdbc.LobCreationContext; | |
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess; | |
import org.hibernate.engine.query.spi.HQLQueryPlan; | |
import org.hibernate.engine.query.spi.NativeSQLQueryPlan; | |
+import org.hibernate.engine.query.spi.ParameterMetadata; | |
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; | |
import org.hibernate.engine.spi.EntityKey; | |
import org.hibernate.engine.spi.NamedQueryDefinition; | |
@@ -148,10 +149,11 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession | |
if ( nsqlqd==null ) { | |
throw new MappingException( "Named query not known: " + queryName ); | |
} | |
+ ParameterMetadata parameterMetadata = factory.getQueryPlanCache().getSQLParameterMetadata( nsqlqd.getQueryString() ); | |
query = new SQLQueryImpl( | |
nsqlqd, | |
this, | |
- factory.getQueryPlanCache().getSQLParameterMetadata( nsqlqd.getQueryString() ) | |
+ parameterMetadata | |
); | |
query.setComment( "named native SQL query " + queryName ); | |
nqd = nsqlqd; | |
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java | |
index 5ded9a8..33abf9c 100644 | |
--- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java | |
+++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java | |
@@ -1120,6 +1120,8 @@ public final class SessionFactoryImpl | |
catch ( MappingException e ) { | |
errors.put( queryName, e ); | |
} | |
+ | |
+ | |
} | |
if ( LOG.isDebugEnabled() ) { | |
LOG.debugf( "Checking %s named SQL queries", namedSqlQueries.size() ); | |
@@ -1161,6 +1163,7 @@ public final class SessionFactoryImpl | |
catch ( MappingException e ) { | |
errors.put( queryName, e ); | |
} | |
+ | |
} | |
return errors; | |
@@ -1250,11 +1253,15 @@ public final class SessionFactoryImpl | |
} | |
public Type[] getReturnTypes(String queryString) throws HibernateException { | |
- return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ).getReturnMetadata().getReturnTypes(); | |
+ return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ) | |
+ .getReturnMetadata() | |
+ .getReturnTypes(); | |
} | |
public String[] getReturnAliases(String queryString) throws HibernateException { | |
- return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ).getReturnMetadata().getReturnAliases(); | |
+ return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ) | |
+ .getReturnMetadata() | |
+ .getReturnAliases(); | |
} | |
public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException { | |
@@ -1416,6 +1423,8 @@ public final class SessionFactoryImpl | |
settings.getRegionFactory().stop(); | |
+ queryPlanCache.destroy(); | |
+ | |
if ( settings.isAutoDropSchema() ) { | |
schemaExport.drop( false, true ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment