diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/CacheImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/CacheImplementor.java new file mode 100644 index 0000000000..943158f4fe --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/CacheImplementor.java @@ -0,0 +1,90 @@ +package org.hibernate.engine.spi; + +import java.io.Serializable; +import java.util.Map; + +import org.hibernate.Cache; +import org.hibernate.HibernateException; +import org.hibernate.cache.spi.QueryCache; +import org.hibernate.cache.spi.Region; +import org.hibernate.cache.spi.RegionFactory; +import org.hibernate.cache.spi.UpdateTimestampsCache; +import org.hibernate.service.Service; + +/** + * Define internal contact of Cache API + * + * @author Strong Liu + */ +public interface CacheImplementor extends Service, Cache, Serializable { + + /** + * Close all cache regions. + */ + public void close(); + + /** + * Get query cache by region name or create a new one if none exist. + *

+ * If the region name is null, then default query cache region will be returned. + * + * @param regionName Query cache region name. + * @return The {@code QueryCache} associated with the region name, or default query cache if the region name is null. + * @throws HibernateException {@code HibernateException} maybe thrown when the creation of new QueryCache instance. + */ + public QueryCache getQueryCache(String regionName) throws HibernateException; + + /** + * Get the default {@code QueryCache}. + */ + public QueryCache getQueryCache(); + + /** + * Add {@code Region} to this Cache scope. + * + * @param name The region name. + * @param region The {@code Region} instance. + */ + public void addCacheRegion(String name, Region region); + + /** + * Get {@code UpdateTimestampsCache} instance managed by the {@code SessionFactory}. + */ + public UpdateTimestampsCache getUpdateTimestampsCache(); + + /** + * Clean up the default {@code QueryCache}. + * + * @throws HibernateException + */ + public void evictQueries() throws HibernateException; + + /** + * Get second level cache region by its name. + * + * @param regionName The region name. + * @return The second level cache region. + */ + public Region getSecondLevelCacheRegion(String regionName); + + /** + * Get natural id cache region by its name. + * + * @param regionName The region name. + * @return The natural id cache region. + */ + public Region getNaturalIdCacheRegion(String regionName); + + /** + * Get all cache regions, including query cache. + * + * @return The map contains all cache regions with region name as the key. + */ + public Map getAllSecondLevelCacheRegions(); + + /** + * + * @return The {@code RegionFactory} + */ + public RegionFactory getRegionFactory(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/CacheInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/CacheInitiator.java new file mode 100644 index 0000000000..40741e4d8c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/CacheInitiator.java @@ -0,0 +1,29 @@ +package org.hibernate.engine.spi; + +import org.hibernate.cfg.Configuration; +import org.hibernate.metamodel.source.MetadataImplementor; +import org.hibernate.service.spi.ServiceRegistryImplementor; +import org.hibernate.service.spi.SessionFactoryServiceInitiator; +import org.hibernate.internal.CacheImpl; + +/** + * @author Strong Liu + */ +public class CacheInitiator implements SessionFactoryServiceInitiator { + public static final CacheInitiator INSTANCE = new CacheInitiator(); + + @Override + public CacheImplementor initiateService(SessionFactoryImplementor sessionFactory, Configuration configuration, ServiceRegistryImplementor registry) { + return new CacheImpl( sessionFactory ); + } + + @Override + public CacheImplementor initiateService(SessionFactoryImplementor sessionFactory, MetadataImplementor metadata, ServiceRegistryImplementor registry) { + return new CacheImpl( sessionFactory ); + } + + @Override + public Class getServiceInitiated() { + return CacheImplementor.class; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java index c01e229770..71d7d59140 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java @@ -92,6 +92,13 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { */ public EntityPersister getEntityPersister(String entityName) throws MappingException; + /** + * Get all entity persisters as a Map, which entity name its the key and the persister is the value. + * + * @return The Map contains all entity persisters. + */ + public Map getEntityPersisters(); + /** * Get the persister object for a collection role. * @@ -102,6 +109,13 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { */ public CollectionPersister getCollectionPersister(String role) throws MappingException; + /** + * Get all collection persisters as a Map, which collection role as the key and the persister is the value. + * + * @return The Map contains all collection persisters. + */ + public Map getCollectionPersisters(); + /** * Get the JdbcServices. * @return the JdbcServices diff --git a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java new file mode 100644 index 0000000000..9b34529772 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java @@ -0,0 +1,334 @@ +package org.hibernate.internal; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.jboss.logging.Logger; + +import org.hibernate.HibernateException; +import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.QueryCache; +import org.hibernate.cache.spi.Region; +import org.hibernate.cache.spi.RegionFactory; +import org.hibernate.cache.spi.UpdateTimestampsCache; +import org.hibernate.cfg.Settings; +import org.hibernate.engine.spi.CacheImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.pretty.MessageHelper; + +/** + * @author Strong Liu + */ +public class CacheImpl implements CacheImplementor { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + CacheImpl.class.getName() + ); + private final SessionFactoryImplementor sessionFactory; + private final Settings settings; + private final transient QueryCache queryCache; + private final transient RegionFactory regionFactory; + private final transient UpdateTimestampsCache updateTimestampsCache; + private final transient ConcurrentMap queryCaches; + private final transient ConcurrentMap allCacheRegions = new ConcurrentHashMap(); + + public CacheImpl(SessionFactoryImplementor sessionFactory) { + this.sessionFactory = sessionFactory; + this.settings = sessionFactory.getSettings(); + //todo should get this from service registry + this.regionFactory = settings.getRegionFactory(); + regionFactory.start( settings, sessionFactory.getProperties() ); + if ( settings.isQueryCacheEnabled() ) { + updateTimestampsCache = new UpdateTimestampsCache( + settings, + sessionFactory.getProperties(), + sessionFactory + ); + queryCache = settings.getQueryCacheFactory() + .getQueryCache( null, updateTimestampsCache, settings, sessionFactory.getProperties() ); + queryCaches = new ConcurrentHashMap(); + allCacheRegions.put( updateTimestampsCache.getRegion().getName(), updateTimestampsCache.getRegion() ); + allCacheRegions.put( queryCache.getRegion().getName(), queryCache.getRegion() ); + } + else { + updateTimestampsCache = null; + queryCache = null; + queryCaches = null; + } + } + + @Override + public boolean containsEntity(Class entityClass, Serializable identifier) { + return containsEntity( entityClass.getName(), identifier ); + } + + @Override + public boolean containsEntity(String entityName, Serializable identifier) { + EntityPersister p = sessionFactory.getEntityPersister( entityName ); + return p.hasCache() && + p.getCacheAccessStrategy().getRegion().contains( buildCacheKey( identifier, p ) ); + } + + @Override + public void evictEntity(Class entityClass, Serializable identifier) { + evictEntity( entityClass.getName(), identifier ); + } + + @Override + public void evictEntity(String entityName, Serializable identifier) { + EntityPersister p = sessionFactory.getEntityPersister( entityName ); + if ( p.hasCache() ) { + if ( LOG.isDebugEnabled() ) { + LOG.debugf( + "Evicting second-level cache: %s", + MessageHelper.infoString( p, identifier, sessionFactory ) + ); + } + p.getCacheAccessStrategy().evict( buildCacheKey( identifier, p ) ); + } + } + + private CacheKey buildCacheKey(Serializable identifier, EntityPersister p) { + return new CacheKey( + identifier, + p.getIdentifierType(), + p.getRootEntityName(), + null, // have to assume non tenancy + sessionFactory + ); + } + + @Override + public void evictEntityRegion(Class entityClass) { + evictEntityRegion( entityClass.getName() ); + } + + @Override + public void evictEntityRegion(String entityName) { + EntityPersister p = sessionFactory.getEntityPersister( entityName ); + if ( p.hasCache() ) { + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Evicting second-level cache: %s", p.getEntityName() ); + } + p.getCacheAccessStrategy().evictAll(); + } + } + + @Override + public void evictEntityRegions() { + for ( String s : sessionFactory.getEntityPersisters().keySet() ) { + evictEntityRegion( s ); + } + } + + @Override + public void evictNaturalIdRegion(Class entityClass) { + evictNaturalIdRegion( entityClass.getName() ); + } + + @Override + public void evictNaturalIdRegion(String entityName) { + EntityPersister p = sessionFactory.getEntityPersister( entityName ); + if ( p.hasNaturalIdCache() ) { + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Evicting natural-id cache: %s", p.getEntityName() ); + } + p.getNaturalIdCacheAccessStrategy().evictAll(); + } + } + + @Override + public void evictNaturalIdRegions() { + for ( String s : sessionFactory.getEntityPersisters().keySet() ) { + evictNaturalIdRegion( s ); + } + } + + @Override + public boolean containsCollection(String role, Serializable ownerIdentifier) { + CollectionPersister p = sessionFactory.getCollectionPersister( role ); + return p.hasCache() && + p.getCacheAccessStrategy().getRegion().contains( buildCacheKey( ownerIdentifier, p ) ); + } + + @Override + public void evictCollection(String role, Serializable ownerIdentifier) { + CollectionPersister p = sessionFactory.getCollectionPersister( role ); + if ( p.hasCache() ) { + if ( LOG.isDebugEnabled() ) { + LOG.debugf( + "Evicting second-level cache: %s", + MessageHelper.collectionInfoString( p, ownerIdentifier, sessionFactory ) + ); + } + CacheKey cacheKey = buildCacheKey( ownerIdentifier, p ); + p.getCacheAccessStrategy().evict( cacheKey ); + } + } + + private CacheKey buildCacheKey(Serializable ownerIdentifier, CollectionPersister p) { + return new CacheKey( + ownerIdentifier, + p.getKeyType(), + p.getRole(), + null, // have to assume non tenancy + sessionFactory + ); + } + + @Override + public void evictCollectionRegion(String role) { + CollectionPersister p = sessionFactory.getCollectionPersister( role ); + if ( p.hasCache() ) { + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Evicting second-level cache: %s", p.getRole() ); + } + p.getCacheAccessStrategy().evictAll(); + } + } + + @Override + public void evictCollectionRegions() { + for ( String s : sessionFactory.getCollectionPersisters().keySet() ) { + evictCollectionRegion( s ); + } + } + + @Override + public boolean containsQuery(String regionName) { + return queryCaches.containsKey( regionName ); + } + + @Override + public void evictDefaultQueryRegion() { + if ( sessionFactory.getSettings().isQueryCacheEnabled() ) { + sessionFactory.getQueryCache().clear(); + } + } + + @Override + public void evictQueryRegion(String regionName) { + if ( regionName == null ) { + throw new NullPointerException( + "Region-name cannot be null (use Cache#evictDefaultQueryRegion to evict the default query cache)" + ); + } + if ( sessionFactory.getSettings().isQueryCacheEnabled() ) { + QueryCache namedQueryCache = queryCaches.get( regionName ); + // TODO : cleanup entries in queryCaches + allCacheRegions ? + if ( namedQueryCache != null ) { + namedQueryCache.clear(); + } + } + } + + @Override + public void evictQueryRegions() { + if ( CollectionHelper.isEmpty( queryCaches ) ) { + return; + } + for ( QueryCache queryCache : queryCaches.values() ) { + queryCache.clear(); + // TODO : cleanup entries in queryCaches + allCacheRegions ? + } + } + + @Override + public void close() { + if ( settings.isQueryCacheEnabled() ) { + queryCache.destroy(); + + Iterator iter = queryCaches.values().iterator(); + while ( iter.hasNext() ) { + QueryCache cache = (QueryCache) iter.next(); + cache.destroy(); + } + updateTimestampsCache.destroy(); + } + + regionFactory.stop(); + } + + @Override + public QueryCache getQueryCache() { + return queryCache; + } + + @Override + public QueryCache getQueryCache(String regionName) throws HibernateException { + if ( regionName == null ) { + return getQueryCache(); + } + + if ( !settings.isQueryCacheEnabled() ) { + return null; + } + + QueryCache currentQueryCache = queryCaches.get( regionName ); + if ( currentQueryCache == null ) { + synchronized ( allCacheRegions ) { + currentQueryCache = queryCaches.get( regionName ); + if ( currentQueryCache == null ) { + currentQueryCache = settings.getQueryCacheFactory() + .getQueryCache( + regionName, + updateTimestampsCache, + settings, + sessionFactory.getProperties() + ); + queryCaches.put( regionName, currentQueryCache ); + allCacheRegions.put( currentQueryCache.getRegion().getName(), currentQueryCache.getRegion() ); + } + else { + return currentQueryCache; + } + } + } + return currentQueryCache; + } + + @Override + public void addCacheRegion(String name, Region region) { + allCacheRegions.put( name, region ); + } + + @Override + public UpdateTimestampsCache getUpdateTimestampsCache() { + return updateTimestampsCache; + } + + @Override + public void evictQueries() throws HibernateException { + if ( settings.isQueryCacheEnabled() ) { + queryCache.clear(); + } + } + + @Override + public Region getSecondLevelCacheRegion(String regionName) { + return allCacheRegions.get( regionName ); + } + + @Override + public Region getNaturalIdCacheRegion(String regionName) { + return allCacheRegions.get( regionName ); + } + + @SuppressWarnings({ "unchecked" }) + @Override + public Map getAllSecondLevelCacheRegions() { + return new HashMap( allCacheRegions ); + } + + @Override + public RegionFactory getRegionFactory() { + return regionFactory; + } +} 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 866c4f9858..e12a83dbfc 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -59,12 +59,12 @@ import org.hibernate.SessionBuilder; import org.hibernate.SessionFactory; import org.hibernate.SessionFactoryObserver; +import org.hibernate.engine.spi.CacheImplementor; import org.hibernate.engine.spi.SessionOwner; import org.hibernate.StatelessSession; import org.hibernate.StatelessSessionBuilder; import org.hibernate.TypeHelper; import org.hibernate.cache.internal.CacheDataDescriptionImpl; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.NaturalIdRegion; @@ -113,7 +113,6 @@ import org.hibernate.integrator.spi.Integrator; import org.hibernate.integrator.spi.IntegratorService; import org.hibernate.internal.util.ReflectHelper; -import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.mapping.Collection; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.RootClass; @@ -127,10 +126,10 @@ import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.Queryable; import org.hibernate.persister.spi.PersisterFactory; -import org.hibernate.pretty.MessageHelper; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.classloading.spi.ClassLoaderService; +import org.hibernate.service.classloading.spi.ClassLoadingException; import org.hibernate.service.config.spi.ConfigurationService; import org.hibernate.service.jdbc.connections.spi.ConnectionProvider; import org.hibernate.service.jndi.spi.JndiService; @@ -200,16 +199,12 @@ public final class SessionFactoryImpl private final transient Settings settings; private final transient Properties properties; private transient SchemaExport schemaExport; - private final transient QueryCache queryCache; - private final transient UpdateTimestampsCache updateTimestampsCache; - private final transient ConcurrentMap queryCaches; - private final transient ConcurrentMap allCacheRegions = new ConcurrentHashMap(); private final transient CurrentSessionContext currentSessionContext; private final transient SQLFunctionRegistry sqlFunctionRegistry; private final transient SessionFactoryObserverChain observer = new SessionFactoryObserverChain(); private final transient ConcurrentHashMap entityNameResolvers = new ConcurrentHashMap(); private final transient QueryPlanCache queryPlanCache; - private final transient Cache cacheAccess = new CacheImpl(); + private final transient CacheImplementor cacheAccess; private transient boolean isClosed = false; private final transient TypeResolver typeResolver; private final transient TypeHelper typeHelper; @@ -264,6 +259,8 @@ public void handleEntityNotFound(String entityName, Serializable id) { ); this.jdbcServices = this.serviceRegistry.getService( JdbcServices.class ); this.dialect = this.jdbcServices.getDialect(); + this.cacheAccess = this.serviceRegistry.getService( CacheImplementor.class ); + final RegionFactory regionFactory = cacheAccess.getRegionFactory(); this.sqlFunctionRegistry = new SQLFunctionRegistry( getDialect(), cfg.getSqlFunctions() ); if ( observer != null ) { this.observer.addObserver( observer ); @@ -278,9 +275,7 @@ public void handleEntityNotFound(String entityName, Serializable id) { LOG.debugf( "Session factory constructed with filter configurations : %s", filters ); LOG.debugf( "Instantiating session factory with properties: %s", properties ); - // Caches - final RegionFactory regionFactory = settings.getRegionFactory(); - regionFactory.start( settings, properties ); + this.queryPlanCache = new QueryPlanCache( this ); // todo : everything above here consider implementing as standard SF service. specifically: stats, caches, types, function-reg @@ -349,7 +344,7 @@ public void sessionFactoryClosed(SessionFactory factory) { EntityRegion entityRegion = regionFactory.buildEntityRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) ); accessStrategy = entityRegion.buildAccessStrategy( accessType ); entityAccessStrategies.put( cacheRegionName, accessStrategy ); - allCacheRegions.put( cacheRegionName, entityRegion ); + cacheAccess.addCacheRegion( cacheRegionName, entityRegion ); } } @@ -378,7 +373,7 @@ public void sessionFactoryClosed(SessionFactory factory) { if (naturalIdRegion != null) { naturalIdAccessStrategy = naturalIdRegion.buildAccessStrategy( regionFactory.getDefaultAccessType() ); entityAccessStrategies.put( naturalIdCacheRegionName, naturalIdAccessStrategy ); - allCacheRegions.put( naturalIdCacheRegionName, naturalIdRegion ); + cacheAccess.addCacheRegion( naturalIdCacheRegionName, naturalIdRegion ); } } } @@ -410,7 +405,7 @@ public void sessionFactoryClosed(SessionFactory factory) { .decode( model ) ); accessStrategy = collectionRegion.buildAccessStrategy( accessType ); entityAccessStrategies.put( cacheRegionName, accessStrategy ); - allCacheRegions.put( cacheRegionName, collectionRegion ); + cacheAccess.addCacheRegion( cacheRegionName, collectionRegion ); } CollectionPersister persister = serviceRegistry.getService( PersisterFactory.class ).createCollectionPersister( cfg, @@ -506,20 +501,6 @@ public void sessionFactoryClosed(SessionFactory factory) { currentSessionContext = buildCurrentSessionContext(); - if ( settings.isQueryCacheEnabled() ) { - updateTimestampsCache = new UpdateTimestampsCache(settings, properties, this); - queryCache = settings.getQueryCacheFactory() - .getQueryCache(null, updateTimestampsCache, settings, properties); - queryCaches = new ConcurrentHashMap(); - allCacheRegions.put( updateTimestampsCache.getRegion().getName(), updateTimestampsCache.getRegion() ); - allCacheRegions.put( queryCache.getRegion().getName(), queryCache.getRegion() ); - } - else { - updateTimestampsCache = null; - queryCache = null; - queryCaches = null; - } - //checking for named queries if ( settings.isNamedQueryStartupCheckingEnabled() ) { final Map errors = checkNamedQueries(); @@ -717,6 +698,7 @@ public SessionFactoryImpl( this.jdbcServices = this.serviceRegistry.getService( JdbcServices.class ); this.dialect = this.jdbcServices.getDialect(); + this.cacheAccess = this.serviceRegistry.getService( CacheImplementor.class ); // TODO: get SQL functions from JdbcServices (HHH-6559) //this.sqlFunctionRegistry = new SQLFunctionRegistry( this.jdbcServices.getSqlFunctions() ); @@ -740,8 +722,6 @@ public SessionFactoryImpl( LOG.debugf( "Session factory constructed with filter configurations : %s", filters ); LOG.debugf( "Instantiating session factory with properties: %s", properties ); - // TODO: get RegionFactory from service registry - settings.getRegionFactory().start( settings, properties ); this.queryPlanCache = new QueryPlanCache( this ); class IntegratorObserver implements SessionFactoryObserver { @@ -816,7 +796,7 @@ public void sessionFactoryClosed(SessionFactory factory) { ); accessStrategy = entityRegion.buildAccessStrategy( accessType ); entityAccessStrategies.put( cacheRegionName, accessStrategy ); - allCacheRegions.put( cacheRegionName, entityRegion ); + cacheAccess.addCacheRegion( cacheRegionName, entityRegion ); } } EntityPersister cp = serviceRegistry.getService( PersisterFactory.class ).createEntityPersister( @@ -851,7 +831,7 @@ public void sessionFactoryClosed(SessionFactory factory) { ); accessStrategy = collectionRegion.buildAccessStrategy( accessType ); entityAccessStrategies.put( cacheRegionName, accessStrategy ); - allCacheRegions.put( cacheRegionName, collectionRegion ); + cacheAccess.addCacheRegion( cacheRegionName, collectionRegion ); } CollectionPersister persister = serviceRegistry .getService( PersisterFactory.class ) @@ -949,20 +929,6 @@ public void sessionFactoryClosed(SessionFactory factory) { currentSessionContext = buildCurrentSessionContext(); - if ( settings.isQueryCacheEnabled() ) { - updateTimestampsCache = new UpdateTimestampsCache( settings, properties, this ); - queryCache = settings.getQueryCacheFactory() - .getQueryCache( null, updateTimestampsCache, settings, properties ); - queryCaches = new ConcurrentHashMap(); - allCacheRegions.put( updateTimestampsCache.getRegion().getName(), updateTimestampsCache.getRegion() ); - allCacheRegions.put( queryCache.getRegion().getName(), queryCache.getRegion() ); - } - else { - updateTimestampsCache = null; - queryCache = null; - queryCaches = null; - } - //checking for named queries if ( settings.isNamedQueryStartupCheckingEnabled() ) { final Map errors = checkNamedQueries(); @@ -1194,6 +1160,16 @@ public EntityPersister getEntityPersister(String entityName) throws MappingExcep return result; } + @Override + public Map getCollectionPersisters() { + return collectionPersisters; + } + + @Override + public Map getEntityPersisters() { + return entityPersisters; + } + public CollectionPersister getCollectionPersister(String role) throws MappingException { CollectionPersister result = collectionPersisters.get(role); if ( result == null ) { @@ -1308,9 +1284,9 @@ public String[] getImplementors(String className) throws MappingException { final Class clazz; try { - clazz = ReflectHelper.classForName(className); + clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( className ); } - catch (ClassNotFoundException cnfe) { + catch (ClassLoadingException cnfe) { return new String[] { className }; //for a dynamic-class } @@ -1356,10 +1332,10 @@ public String getImportedClassName(String className) { String result = imports.get(className); if (result==null) { try { - ReflectHelper.classForName( className ); + serviceRegistry.getService( ClassLoaderService.class ).classForName( className ); return className; } - catch (ClassNotFoundException cnfe) { + catch (ClassLoadingException cnfe) { return null; } } @@ -1427,18 +1403,7 @@ public void close() throws HibernateException { } } - if ( settings.isQueryCacheEnabled() ) { - queryCache.destroy(); - - iter = queryCaches.values().iterator(); - while ( iter.hasNext() ) { - QueryCache cache = (QueryCache) iter.next(); - cache.destroy(); - } - updateTimestampsCache.destroy(); - } - - settings.getRegionFactory().stop(); + cacheAccess.close(); queryPlanCache.cleanup(); @@ -1457,162 +1422,6 @@ public void close() throws HibernateException { serviceRegistry.destroy(); } - private class CacheImpl implements Cache { - public boolean containsEntity(Class entityClass, Serializable identifier) { - return containsEntity( entityClass.getName(), identifier ); - } - - public boolean containsEntity(String entityName, Serializable identifier) { - EntityPersister p = getEntityPersister( entityName ); - return p.hasCache() && - p.getCacheAccessStrategy().getRegion().contains( buildCacheKey( identifier, p ) ); - } - - public void evictEntity(Class entityClass, Serializable identifier) { - evictEntity( entityClass.getName(), identifier ); - } - - public void evictEntity(String entityName, Serializable identifier) { - EntityPersister p = getEntityPersister( entityName ); - if ( p.hasCache() ) { - if ( LOG.isDebugEnabled() ) { - LOG.debugf( "Evicting second-level cache: %s", - MessageHelper.infoString( p, identifier, SessionFactoryImpl.this ) ); - } - p.getCacheAccessStrategy().evict( buildCacheKey( identifier, p ) ); - } - } - - private CacheKey buildCacheKey(Serializable identifier, EntityPersister p) { - return new CacheKey( - identifier, - p.getIdentifierType(), - p.getRootEntityName(), - null, // have to assume non tenancy - SessionFactoryImpl.this - ); - } - - public void evictEntityRegion(Class entityClass) { - evictEntityRegion( entityClass.getName() ); - } - - public void evictEntityRegion(String entityName) { - EntityPersister p = getEntityPersister( entityName ); - if ( p.hasCache() ) { - if ( LOG.isDebugEnabled() ) { - LOG.debugf( "Evicting second-level cache: %s", p.getEntityName() ); - } - p.getCacheAccessStrategy().evictAll(); - } - } - - public void evictEntityRegions() { - for ( String s : entityPersisters.keySet() ) { - evictEntityRegion( s ); - } - } - - public void evictNaturalIdRegion(Class entityClass) { - evictNaturalIdRegion( entityClass.getName() ); - } - - public void evictNaturalIdRegion(String entityName) { - EntityPersister p = getEntityPersister( entityName ); - if ( p.hasNaturalIdCache() ) { - if ( LOG.isDebugEnabled() ) { - LOG.debugf( "Evicting natural-id cache: %s", p.getEntityName() ); - } - p.getNaturalIdCacheAccessStrategy().evictAll(); - } - } - - public void evictNaturalIdRegions() { - for ( String s : entityPersisters.keySet() ) { - evictNaturalIdRegion( s ); - } - } - - public boolean containsCollection(String role, Serializable ownerIdentifier) { - CollectionPersister p = getCollectionPersister( role ); - return p.hasCache() && - p.getCacheAccessStrategy().getRegion().contains( buildCacheKey( ownerIdentifier, p ) ); - } - - public void evictCollection(String role, Serializable ownerIdentifier) { - CollectionPersister p = getCollectionPersister( role ); - if ( p.hasCache() ) { - if ( LOG.isDebugEnabled() ) { - LOG.debugf( "Evicting second-level cache: %s", - MessageHelper.collectionInfoString( p, ownerIdentifier, SessionFactoryImpl.this ) ); - } - CacheKey cacheKey = buildCacheKey( ownerIdentifier, p ); - p.getCacheAccessStrategy().evict( cacheKey ); - } - } - - private CacheKey buildCacheKey(Serializable ownerIdentifier, CollectionPersister p) { - return new CacheKey( - ownerIdentifier, - p.getKeyType(), - p.getRole(), - null, // have to assume non tenancy - SessionFactoryImpl.this - ); - } - - public void evictCollectionRegion(String role) { - CollectionPersister p = getCollectionPersister( role ); - if ( p.hasCache() ) { - if ( LOG.isDebugEnabled() ) { - LOG.debugf( "Evicting second-level cache: %s", p.getRole() ); - } - p.getCacheAccessStrategy().evictAll(); - } - } - - public void evictCollectionRegions() { - for ( String s : collectionPersisters.keySet() ) { - evictCollectionRegion( s ); - } - } - - public boolean containsQuery(String regionName) { - return queryCaches.containsKey( regionName ); - } - - public void evictDefaultQueryRegion() { - if ( settings.isQueryCacheEnabled() ) { - queryCache.clear(); - } - } - - public void evictQueryRegion(String regionName) { - if ( regionName == null ) { - throw new NullPointerException( - "Region-name cannot be null (use Cache#evictDefaultQueryRegion to evict the default query cache)" - ); - } - if ( settings.isQueryCacheEnabled() ) { - QueryCache namedQueryCache = queryCaches.get( regionName ); - // TODO : cleanup entries in queryCaches + allCacheRegions ? - if ( namedQueryCache != null ) { - namedQueryCache.clear(); - } - } - } - - public void evictQueryRegions() { - if ( CollectionHelper.isEmpty( queryCaches ) ) { - return; - } - for ( QueryCache queryCache : queryCaches.values() ) { - queryCache.clear(); - // TODO : cleanup entries in queryCaches + allCacheRegions ? - } - } - } - public Cache getCache() { return cacheAccess; } @@ -1642,9 +1451,7 @@ public void evictCollection(String roleName) throws HibernateException { } public void evictQueries() throws HibernateException { - if ( settings.isQueryCacheEnabled() ) { - queryCache.clear(); - } + cacheAccess.evictQueries(); } public void evictQueries(String regionName) throws HibernateException { @@ -1652,50 +1459,28 @@ public void evictQueries(String regionName) throws HibernateException { } public UpdateTimestampsCache getUpdateTimestampsCache() { - return updateTimestampsCache; + return cacheAccess.getUpdateTimestampsCache(); } public QueryCache getQueryCache() { - return queryCache; + return cacheAccess.getQueryCache(); } public QueryCache getQueryCache(String regionName) throws HibernateException { - if ( regionName == null ) { - return getQueryCache(); - } - - if ( !settings.isQueryCacheEnabled() ) { - return null; - } - - QueryCache currentQueryCache = queryCaches.get( regionName ); - if ( currentQueryCache == null ) { - synchronized ( allCacheRegions ) { - currentQueryCache = queryCaches.get( regionName ); - if ( currentQueryCache == null ) { - currentQueryCache = settings.getQueryCacheFactory() - .getQueryCache( regionName, updateTimestampsCache, settings, properties ); - queryCaches.put( regionName, currentQueryCache ); - allCacheRegions.put( currentQueryCache.getRegion().getName(), currentQueryCache.getRegion() ); - } else { - return currentQueryCache; - } - } - } - return currentQueryCache; + return cacheAccess.getQueryCache( regionName ); } public Region getSecondLevelCacheRegion(String regionName) { - return allCacheRegions.get( regionName ); + return cacheAccess.getSecondLevelCacheRegion( regionName ); } public Region getNaturalIdCacheRegion(String regionName) { - return allCacheRegions.get( regionName ); + return cacheAccess.getNaturalIdCacheRegion( regionName ); } @SuppressWarnings( {"unchecked"}) public Map getAllSecondLevelCacheRegions() { - return new HashMap( allCacheRegions ); + return cacheAccess.getAllSecondLevelCacheRegions(); } public boolean isClosed() { @@ -1769,7 +1554,7 @@ else if ( "managed".equals( impl ) ) { } else { try { - Class implClass = ReflectHelper.classForName( impl ); + Class implClass = serviceRegistry.getService( ClassLoaderService.class ).classForName( impl ); return ( CurrentSessionContext ) implClass .getConstructor( new Class[] { SessionFactoryImplementor.class } ) .newInstance( this ); diff --git a/hibernate-core/src/main/java/org/hibernate/service/internal/StandardSessionFactoryServiceInitiators.java b/hibernate-core/src/main/java/org/hibernate/service/internal/StandardSessionFactoryServiceInitiators.java index 8a71318101..fcfd9a4e5f 100644 --- a/hibernate-core/src/main/java/org/hibernate/service/internal/StandardSessionFactoryServiceInitiators.java +++ b/hibernate-core/src/main/java/org/hibernate/service/internal/StandardSessionFactoryServiceInitiators.java @@ -27,6 +27,7 @@ import java.util.Collections; import java.util.List; +import org.hibernate.engine.spi.CacheInitiator; import org.hibernate.event.service.internal.EventListenerServiceInitiator; import org.hibernate.service.spi.SessionFactoryServiceInitiator; import org.hibernate.stat.internal.StatisticsInitiator; @@ -45,6 +46,7 @@ private static List buildStandardServiceInitiato serviceInitiators.add( EventListenerServiceInitiator.INSTANCE ); serviceInitiators.add( StatisticsInitiator.INSTANCE ); + serviceInitiators.add( CacheInitiator.INSTANCE ); return Collections.unmodifiableList( serviceInitiators ); }