HHH-10287 - Cache keys no longer include the entity type

This commit is contained in:
Steve Ebersole 2016-06-01 20:51:46 -05:00
parent 114ea15b30
commit 3a0824a037
22 changed files with 395 additions and 108 deletions

View File

@ -13,6 +13,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.registry.selector.spi.StrategyCreator;
import org.hibernate.boot.registry.selector.spi.StrategySelectionException; import org.hibernate.boot.registry.selector.spi.StrategySelectionException;
import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.boot.registry.selector.spi.StrategySelector;
@ -26,8 +27,20 @@ import org.jboss.logging.Logger;
public class StrategySelectorImpl implements StrategySelector { public class StrategySelectorImpl implements StrategySelector {
private static final Logger log = Logger.getLogger( StrategySelectorImpl.class ); private static final Logger log = Logger.getLogger( StrategySelectorImpl.class );
private final Map<Class,Map<String,Class>> namedStrategyImplementorByStrategyMap
= new ConcurrentHashMap<Class, Map<String, Class>>(); public static StrategyCreator STANDARD_STRATEGY_CREATOR = strategyClass -> {
try {
return strategyClass.newInstance();
}
catch (Exception e) {
throw new StrategySelectionException(
String.format( "Could not instantiate named strategy class [%s]", strategyClass.getName() ),
e
);
}
};
private final Map<Class,Map<String,Class>> namedStrategyImplementorByStrategyMap = new ConcurrentHashMap<>();
private final ClassLoaderService classLoaderService; private final ClassLoaderService classLoaderService;
@ -44,7 +57,7 @@ public class StrategySelectorImpl implements StrategySelector {
public <T> void registerStrategyImplementor(Class<T> strategy, String name, Class<? extends T> implementation) { public <T> void registerStrategyImplementor(Class<T> strategy, String name, Class<? extends T> implementation) {
Map<String,Class> namedStrategyImplementorMap = namedStrategyImplementorByStrategyMap.get( strategy ); Map<String,Class> namedStrategyImplementorMap = namedStrategyImplementorByStrategyMap.get( strategy );
if ( namedStrategyImplementorMap == null ) { if ( namedStrategyImplementorMap == null ) {
namedStrategyImplementorMap = new ConcurrentHashMap<String, Class>(); namedStrategyImplementorMap = new ConcurrentHashMap<>();
namedStrategyImplementorByStrategyMap.put( strategy, namedStrategyImplementorMap ); namedStrategyImplementorByStrategyMap.put( strategy, namedStrategyImplementorMap );
} }
@ -126,12 +139,7 @@ public class StrategySelectorImpl implements StrategySelector {
return resolveDefaultableStrategy( return resolveDefaultableStrategy(
strategy, strategy,
strategyReference, strategyReference,
new Callable<T>() { (Callable<T>) () -> defaultValue
@Override
public T call() {
return defaultValue;
}
}
); );
} }
@ -141,6 +149,30 @@ public class StrategySelectorImpl implements StrategySelector {
Class<T> strategy, Class<T> strategy,
Object strategyReference, Object strategyReference,
Callable<T> defaultResolver) { Callable<T> defaultResolver) {
return (T) resolveStrategy( strategy, strategyReference, defaultResolver, STANDARD_STRATEGY_CREATOR );
}
@Override
public <T> T resolveStrategy(
Class<T> strategy,
Object strategyReference,
T defaultValue,
StrategyCreator<T> creator) {
return resolveStrategy(
strategy,
strategyReference,
(Callable<T>) () -> defaultValue,
creator
);
}
@SuppressWarnings("unchecked")
@Override
public <T> T resolveStrategy(
Class<T> strategy,
Object strategyReference,
Callable<T> defaultResolver,
StrategyCreator<T> creator) {
if ( strategyReference == null ) { if ( strategyReference == null ) {
try { try {
return defaultResolver.call(); return defaultResolver.call();
@ -163,7 +195,7 @@ public class StrategySelectorImpl implements StrategySelector {
} }
try { try {
return implementationClass.newInstance(); return creator.create( implementationClass );
} }
catch (Exception e) { catch (Exception e) {
throw new StrategySelectionException( throw new StrategySelectionException(

View File

@ -0,0 +1,14 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.boot.registry.selector.spi;
/**
* @author Steve Ebersole
*/
public interface StrategyCreator<T> {
T create(Class<? extends T> strategyClass);
}

View File

@ -19,9 +19,9 @@ import org.hibernate.service.Service;
* StrategySelector manages resolution of particular implementation by (possibly short) name via the * StrategySelector manages resolution of particular implementation by (possibly short) name via the
* {@link #selectStrategyImplementor} method, which is the main contract here. As indicated in the docs of that * {@link #selectStrategyImplementor} method, which is the main contract here. As indicated in the docs of that
* method the given name might be either a short registered name or the implementation FQN. As an example, consider * method the given name might be either a short registered name or the implementation FQN. As an example, consider
* resolving the {@link org.hibernate.engine.transaction.spi.TransactionFactory} implementation to use. To use the * resolving the {@link org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder} implementation to use. To use the
* JDBC-based TransactionFactory the passed name might be either {@code "jdbc"} or * JDBC-based TransactionCoordinatorBuilder the passed name might be either {@code "jdbc"} or
* {@code "org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory"} (which is the FQN). * {@code "org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl"} (which is the FQN).
* <p/> * <p/>
* Strategy implementations can be managed by {@link #registerStrategyImplementor} and * Strategy implementations can be managed by {@link #registerStrategyImplementor} and
* {@link #unRegisterStrategyImplementor}. Originally designed to help the OSGi use case, though no longer used there. * {@link #unRegisterStrategyImplementor}. Originally designed to help the OSGi use case, though no longer used there.
@ -135,4 +135,8 @@ public interface StrategySelector extends Service {
* @return The strategy instance * @return The strategy instance
*/ */
<T> T resolveDefaultableStrategy(Class<T> strategy, Object strategyReference, Callable<T> defaultResolver); <T> T resolveDefaultableStrategy(Class<T> strategy, Object strategyReference, Callable<T> defaultResolver);
<T> T resolveStrategy(Class<T> strategy, Object strategyReference, Callable<T> defaultResolver, StrategyCreator<T> creator);
<T> T resolveStrategy(Class<T> strategy, Object strategyReference, T defaultValue, StrategyCreator<T> creator);
} }

View File

@ -19,6 +19,7 @@ import org.hibernate.SessionFactoryObserver;
import org.hibernate.boot.SchemaAutoTooling; import org.hibernate.boot.SchemaAutoTooling;
import org.hibernate.boot.TempTableDdlTransactionHandling; import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.QueryCacheFactory; import org.hibernate.cache.spi.QueryCacheFactory;
import org.hibernate.cfg.BaselineSessionEventsListenerBuilder; import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.context.spi.CurrentTenantIdentifierResolver;

View File

@ -9,17 +9,16 @@ package org.hibernate.cache.internal;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.boot.registry.StandardServiceInitiator; import org.hibernate.boot.registry.StandardServiceInitiator;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.jboss.logging.Logger;
/** /**
* Initiator for the {@link RegionFactory} service. * Initiator for the {@link RegionFactory} service.
* *
@ -27,9 +26,7 @@ import org.jboss.logging.Logger;
* @author Brett Meyer * @author Brett Meyer
*/ */
public class RegionFactoryInitiator implements StandardServiceInitiator<RegionFactory> { public class RegionFactoryInitiator implements StandardServiceInitiator<RegionFactory> {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( RegionFactoryInitiator.class );
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class,
RegionFactoryInitiator.class.getName() );
/** /**
* Singleton access * Singleton access
@ -63,26 +60,16 @@ public class RegionFactoryInitiator implements StandardServiceInitiator<RegionFa
// The cache provider is needed when we either have second-level cache enabled // The cache provider is needed when we either have second-level cache enabled
// or query cache enabled. Note that useSecondLevelCache is enabled by default // or query cache enabled. Note that useSecondLevelCache is enabled by default
final String setting = ConfigurationHelper.getString( AvailableSettings.CACHE_REGION_FACTORY, if ( useSecondLevelCache || useQueryCache ) {
configurationValues, null ); final Object setting = configurationValues != null
if ( ( useSecondLevelCache || useQueryCache ) && setting != null ) { ? configurationValues.get( AvailableSettings.CACHE_REGION_FACTORY )
try { : null;
final Class<? extends RegionFactory> regionFactoryClass = registry.getService( StrategySelector.class ) regionFactory = registry.getService( StrategySelector.class ).resolveStrategy(
.selectStrategyImplementor( RegionFactory.class, setting ); RegionFactory.class,
try { setting,
regionFactory = regionFactoryClass.getConstructor( Properties.class ).newInstance( p ); NoCachingRegionFactory.INSTANCE,
} new StrategyCreatorRegionFactoryImpl( p )
catch ( NoSuchMethodException e ) { );
// no constructor accepting Properties found, try no arg constructor
LOG.debugf(
"%s did not provide constructor accepting java.util.Properties; attempting no-arg constructor.",
regionFactoryClass.getSimpleName() );
regionFactory = regionFactoryClass.getConstructor().newInstance();
}
}
catch ( Exception e ) {
throw new HibernateException( "could not instantiate RegionFactory [" + setting + "]", e );
}
} }
LOG.debugf( "Cache region factory : %s", regionFactory.getClass().getName() ); LOG.debugf( "Cache region factory : %s", regionFactory.getClass().getName() );

View File

@ -0,0 +1,68 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.cache.internal;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Properties;
import org.hibernate.boot.registry.selector.spi.StrategyCreator;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.service.spi.ServiceException;
import org.jboss.logging.Logger;
/**
* @author Steve Ebersole
*/
public class StrategyCreatorRegionFactoryImpl implements StrategyCreator<RegionFactory> {
private static final Logger log = Logger.getLogger( StrategyCreatorRegionFactoryImpl.class );
private final Properties properties;
public StrategyCreatorRegionFactoryImpl(Properties properties) {
this.properties = properties;
}
@Override
public RegionFactory create(Class<? extends RegionFactory> strategyClass) {
assert RegionFactory.class.isAssignableFrom( strategyClass );
// first look for a constructor accepting Properties
try {
final Constructor<? extends RegionFactory> ctor = strategyClass.getConstructor( Properties.class );
return ctor.newInstance( properties );
}
catch ( NoSuchMethodException e ) {
log.debugf( "RegionFactory impl [%s] did not provide constructor accepting Properties", strategyClass.getName() );
}
catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
throw new ServiceException( "Unable to call constructor of RegionFactory impl [" + strategyClass.getName() + "]", e );
}
// next try Map
try {
final Constructor<? extends RegionFactory> ctor = strategyClass.getConstructor( Map.class );
return ctor.newInstance( properties );
}
catch ( NoSuchMethodException e ) {
log.debugf( "RegionFactory impl [%s] did not provide constructor accepting Properties", strategyClass.getName() );
}
catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
throw new ServiceException( "Unable to call constructor of RegionFactory impl [" + strategyClass.getName() + "]", e );
}
// finally try no-arg
try {
return strategyClass.newInstance();
}
catch (IllegalAccessException | InstantiationException e) {
throw new ServiceException( "Unable to call constructor of RegionFactory impl [" + strategyClass.getName() + "]", e );
}
}
}

View File

@ -891,14 +891,31 @@ public interface AvailableSettings {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** /**
* The {@link org.hibernate.cache.spi.RegionFactory} implementation class * The {@link org.hibernate.cache.spi.RegionFactory} implementation. Can refer to:<ul>
* <li>an Object implementing {@link org.hibernate.cache.spi.RegionFactory}</li>
* <li>a Class implementing {@link org.hibernate.cache.spi.RegionFactory}</li>
* <li>FQN of a Class implementing {@link org.hibernate.cache.spi.RegionFactory}</li>
* </ul>
*/ */
String CACHE_REGION_FACTORY = "hibernate.cache.region.factory_class"; String CACHE_REGION_FACTORY = "hibernate.cache.region.factory_class";
/**
* Allow control to specify the {@link org.hibernate.cache.spi.CacheKeysFactory} impl to use.
* Can refer to:<ul>
* <li>an Object implementing {@link org.hibernate.cache.spi.CacheKeysFactory}</li>
* <li>a Class implementing {@link org.hibernate.cache.spi.CacheKeysFactory}</li>
* <li>FQN of a Class implementing {@link org.hibernate.cache.spi.CacheKeysFactory}</li>
* </ul>
*
* @since 5.2 - note that currently this is only honored for hibernate-infinispan
*/
String CACHE_KEYS_FACTORY = "hibernate.cache.keys_factory";
/** /**
* The <tt>CacheProvider</tt> implementation class * The <tt>CacheProvider</tt> implementation class
*/ */
String CACHE_PROVIDER_CONFIG = "hibernate.cache.provider_configuration_file_resource_path"; String CACHE_PROVIDER_CONFIG = "hibernate.cache.provider_configuration_file_resource_path";
/** /**
* Enable the second-level cache (enabled by default) * Enable the second-level cache (enabled by default)
*/ */
@ -1474,5 +1491,4 @@ public interface AvailableSettings {
* The default behavior is to allow access unless the session is bootstrapped via JPA. * The default behavior is to allow access unless the session is bootstrapped via JPA.
*/ */
String ALLOW_JTA_TRANSACTION_ACCESS = "hibernate.jta.allowTransactionAccess"; String ALLOW_JTA_TRANSACTION_ACCESS = "hibernate.jta.allowTransactionAccess";
} }

View File

@ -0,0 +1,94 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.cache;
import java.util.Properties;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.Session;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.internal.SimpleCacheKeysFactory;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.testing.cache.CachingRegionFactory;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertNull;
/**
* @author Steve Ebersole
*/
public class SharedRegionTest extends BaseNonConfigCoreFunctionalTestCase {
@Override
protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) {
super.configureStandardServiceRegistryBuilder( ssrb );
ssrb.applySetting( AvailableSettings.USE_SECOND_LEVEL_CACHE, true );
ssrb.applySetting( AvailableSettings.CACHE_REGION_FACTORY, new CachingRegionFactory() );
}
@Override
protected void applyMetadataSources(MetadataSources metadataSources) {
super.applyMetadataSources( metadataSources );
metadataSources.addAnnotatedClass( StateCodes.class );
metadataSources.addAnnotatedClass( ZipCodes.class );
}
@Test
public void test() {
// create a StateCodes
Session s = openSession();
s.beginTransaction();
s.save( new StateCodes( 1 ) );
s.getTransaction().commit();
s.close();
// now try to load a ZipCodes using the same id : should just return null rather than blow up :)
s = openSession();
s.beginTransaction();
ZipCodes zc = s.find( ZipCodes.class, 1 );
assertNull( zc );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
s.find( ZipCodes.class, 1 );
s.getTransaction().commit();
s.close();
}
@Entity( name="StateCodes" )
@Cache( region="com.acme.referenceData", usage = CacheConcurrencyStrategy.READ_WRITE )
public static class StateCodes {
@Id
public Integer id;
public StateCodes() {
}
public StateCodes(Integer id) {
this.id = id;
}
}
@Entity( name = "ZipCodes" )
@Cache( region="com.acme.referenceData", usage = CacheConcurrencyStrategy.READ_WRITE )
public static class ZipCodes {
@Id
public Integer id;
}
}

View File

@ -18,6 +18,7 @@ import java.util.function.Consumer;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.MultiTenancyStrategy; import org.hibernate.MultiTenancyStrategy;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException; import org.hibernate.cache.CacheException;
import org.hibernate.cache.infinispan.collection.CollectionRegionImpl; import org.hibernate.cache.infinispan.collection.CollectionRegionImpl;
@ -42,6 +43,7 @@ import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion; import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
@ -273,6 +275,7 @@ public class InfinispanRegionFactory implements RegionFactory {
*/ */
protected final Map<String, ConfigurationBuilder> configOverrides = new HashMap<>(); protected final Map<String, ConfigurationBuilder> configOverrides = new HashMap<>();
private CacheKeysFactory cacheKeysFactory;
private ConfigurationBuilderHolder defaultConfiguration; private ConfigurationBuilderHolder defaultConfiguration;
private final Map<DataType, Configuration> dataTypeConfigurations = new HashMap<>(); private final Map<DataType, Configuration> dataTypeConfigurations = new HashMap<>();
private EmbeddedCacheManager manager; private EmbeddedCacheManager manager;
@ -301,22 +304,27 @@ public class InfinispanRegionFactory implements RegionFactory {
} }
@Override @Override
public CollectionRegion buildCollectionRegion( public CollectionRegion buildCollectionRegion(String regionName, Map<String, Object> configValues, CacheDataDescription metadata) {
String regionName,
Properties properties,
CacheDataDescription metadata) throws CacheException {
if ( log.isDebugEnabled() ) { if ( log.isDebugEnabled() ) {
log.debug( "Building collection cache region [" + regionName + "]" ); log.debug( "Building collection cache region [" + regionName + "]" );
} }
final AdvancedCache cache = getCache( regionName, DataType.COLLECTION, metadata); final AdvancedCache cache = getCache( regionName, DataType.COLLECTION, metadata);
final CollectionRegionImpl region = new CollectionRegionImpl( cache, regionName, transactionManager, metadata, this, buildCacheKeysFactory() ); final CollectionRegionImpl region = new CollectionRegionImpl( cache, regionName, transactionManager, metadata, this, getCacheKeysFactory() );
startRegion( region ); startRegion( region );
return region; return region;
} }
@Override @Override
public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) @SuppressWarnings("unchecked")
throws CacheException { public CollectionRegion buildCollectionRegion(
String regionName,
Properties properties,
CacheDataDescription metadata) throws CacheException {
return buildCollectionRegion( regionName, (Map) properties, metadata );
}
@Override
public EntityRegion buildEntityRegion(String regionName, Map<String, Object> configValues, CacheDataDescription metadata) {
if ( log.isDebugEnabled() ) { if ( log.isDebugEnabled() ) {
log.debugf( log.debugf(
"Building entity cache region [%s] (mutable=%s, versioned=%s)", "Building entity cache region [%s] (mutable=%s, versioned=%s)",
@ -326,26 +334,36 @@ public class InfinispanRegionFactory implements RegionFactory {
); );
} }
final AdvancedCache cache = getCache( regionName, metadata.isMutable() ? DataType.ENTITY : DataType.IMMUTABLE_ENTITY, metadata ); final AdvancedCache cache = getCache( regionName, metadata.isMutable() ? DataType.ENTITY : DataType.IMMUTABLE_ENTITY, metadata );
final EntityRegionImpl region = new EntityRegionImpl( cache, regionName, transactionManager, metadata, this, buildCacheKeysFactory() ); final EntityRegionImpl region = new EntityRegionImpl( cache, regionName, transactionManager, metadata, this, getCacheKeysFactory() );
startRegion( region ); startRegion( region );
return region; return region;
} }
@Override @Override
public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) @SuppressWarnings("unchecked")
throws CacheException { public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) {
return buildEntityRegion( regionName, (Map) properties, metadata );
}
@Override
public NaturalIdRegion buildNaturalIdRegion(String regionName, Map<String, Object> configValues, CacheDataDescription metadata) {
if ( log.isDebugEnabled() ) { if ( log.isDebugEnabled() ) {
log.debug("Building natural id cache region [" + regionName + "]"); log.debug("Building natural id cache region [" + regionName + "]");
} }
final AdvancedCache cache = getCache( regionName, DataType.NATURAL_ID, metadata); final AdvancedCache cache = getCache( regionName, DataType.NATURAL_ID, metadata);
final NaturalIdRegionImpl region = new NaturalIdRegionImpl( cache, regionName, transactionManager, metadata, this, buildCacheKeysFactory()); final NaturalIdRegionImpl region = new NaturalIdRegionImpl( cache, regionName, transactionManager, metadata, this, getCacheKeysFactory());
startRegion( region ); startRegion( region );
return region; return region;
} }
@Override @Override
public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) @SuppressWarnings("unchecked")
throws CacheException { public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) {
return buildNaturalIdRegion( regionName, (Map) properties, metadata );
}
@Override
public QueryResultsRegion buildQueryResultsRegion(String regionName, Map<String, Object> configValues) {
if ( log.isDebugEnabled() ) { if ( log.isDebugEnabled() ) {
log.debug( "Building query results cache region [" + regionName + "]" ); log.debug( "Building query results cache region [" + regionName + "]" );
} }
@ -357,8 +375,13 @@ public class InfinispanRegionFactory implements RegionFactory {
} }
@Override @Override
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) @SuppressWarnings("unchecked")
throws CacheException { public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) {
return buildQueryResultsRegion( regionName, (Map) properties );
}
@Override
public TimestampsRegion buildTimestampsRegion(String regionName, Map<String, Object> configValues) {
if ( log.isDebugEnabled() ) { if ( log.isDebugEnabled() ) {
log.debug( "Building timestamps cache region [" + regionName + "]" ); log.debug( "Building timestamps cache region [" + regionName + "]" );
} }
@ -368,6 +391,12 @@ public class InfinispanRegionFactory implements RegionFactory {
return region; return region;
} }
@Override
@SuppressWarnings("unchecked")
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) {
return buildTimestampsRegion( regionName, (Map) properties );
}
protected TimestampsRegionImpl createTimestampsRegion( protected TimestampsRegionImpl createTimestampsRegion(
AdvancedCache cache, String regionName) { AdvancedCache cache, String regionName) {
if ( Caches.isClustered(cache) ) { if ( Caches.isClustered(cache) ) {
@ -382,13 +411,8 @@ public class InfinispanRegionFactory implements RegionFactory {
return dataTypeConfigurations.get(DataType.PENDING_PUTS); return dataTypeConfigurations.get(DataType.PENDING_PUTS);
} }
private CacheKeysFactory buildCacheKeysFactory() { private CacheKeysFactory getCacheKeysFactory() {
if (settings.getMultiTenancyStrategy() != MultiTenancyStrategy.NONE) { return cacheKeysFactory;
return DefaultCacheKeysFactory.INSTANCE;
}
else {
return SimpleCacheKeysFactory.INSTANCE;
}
} }
@Override @Override
@ -418,6 +442,10 @@ public class InfinispanRegionFactory implements RegionFactory {
@Override @Override
public void start(SessionFactoryOptions settings, Properties properties) throws CacheException { public void start(SessionFactoryOptions settings, Properties properties) throws CacheException {
log.debug( "Starting Infinispan region factory" ); log.debug( "Starting Infinispan region factory" );
// determine the CacheKeysFactory to use...
this.cacheKeysFactory = determineCacheKeysFactory( settings, properties );
try { try {
this.settings = settings; this.settings = settings;
transactionManagerlookup = createTransactionManagerLookup( settings, properties ); transactionManagerlookup = createTransactionManagerLookup( settings, properties );
@ -449,6 +477,18 @@ public class InfinispanRegionFactory implements RegionFactory {
} }
} }
private CacheKeysFactory determineCacheKeysFactory(SessionFactoryOptions settings, Properties properties) {
final CacheKeysFactory implicitFactory = settings.getMultiTenancyStrategy() != MultiTenancyStrategy.NONE
? DefaultCacheKeysFactory.INSTANCE
: SimpleCacheKeysFactory.INSTANCE;
return settings.getServiceRegistry().getService( StrategySelector.class ).resolveDefaultableStrategy(
CacheKeysFactory.class,
properties.get( AvailableSettings.CACHE_KEYS_FACTORY ),
implicitFactory
);
}
/* This method is overridden in WildFly, so the signature must not change. */ /* This method is overridden in WildFly, so the signature must not change. */
/* In WF, the global configuration setting is ignored */ /* In WF, the global configuration setting is ignored */
protected EmbeddedCacheManager createCacheManager(Properties properties, ServiceRegistry serviceRegistry) { protected EmbeddedCacheManager createCacheManager(Properties properties, ServiceRegistry serviceRegistry) {

View File

@ -6,7 +6,6 @@
*/ */
package org.hibernate.testing.cache; package org.hibernate.testing.cache;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -40,12 +39,12 @@ class BaseCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implem
@Override @Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); return region.getRegionFactory().getCacheKeysFactory().createCollectionKey( id, persister, factory, tenantIdentifier );
} }
@Override @Override
public Object getCacheKeyId(Object cacheKey) { public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.getCollectionId(cacheKey); return region.getRegionFactory().getCacheKeysFactory().getCollectionId( cacheKey );
} }
} }

View File

@ -7,7 +7,6 @@
package org.hibernate.testing.cache; package org.hibernate.testing.cache;
import org.hibernate.cache.CacheException; import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.cache.spi.access.SoftLock;
@ -65,11 +64,11 @@ class BaseEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements
@Override @Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); return region.getRegionFactory().getCacheKeysFactory().createEntityKey( id, persister, factory, tenantIdentifier );
} }
@Override @Override
public Object getCacheKeyId(Object cacheKey) { public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.getEntityId(cacheKey); return region.getRegionFactory().getCacheKeysFactory().getEntityId( cacheKey );
} }
} }

View File

@ -18,8 +18,8 @@ import org.jboss.logging.Logger;
class BaseGeneralDataRegion extends BaseRegion implements GeneralDataRegion { class BaseGeneralDataRegion extends BaseRegion implements GeneralDataRegion {
private static final Logger LOG = Logger.getLogger( BaseGeneralDataRegion.class.getName() ); private static final Logger LOG = Logger.getLogger( BaseGeneralDataRegion.class.getName() );
BaseGeneralDataRegion(String name) { BaseGeneralDataRegion(CachingRegionFactory cachingRegionFactory, String name) {
super( name ); super( cachingRegionFactory, name );
} }
@Override @Override

View File

@ -7,7 +7,6 @@
package org.hibernate.testing.cache; package org.hibernate.testing.cache;
import org.hibernate.cache.CacheException; import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.cache.spi.access.SoftLock;
@ -61,11 +60,11 @@ class BaseNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy impleme
@Override @Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) { public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); return region.getRegionFactory().getCacheKeysFactory().createNaturalIdKey( naturalIdValues, persister, session );
} }
@Override @Override
public Object[] getNaturalIdValues(Object cacheKey) { public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.getNaturalIdValues( cacheKey ); return region.getRegionFactory().getCacheKeysFactory().getNaturalIdValues( cacheKey );
} }
} }

View File

@ -17,17 +17,19 @@ import org.hibernate.cache.spi.Region;
* @author Strong Liu * @author Strong Liu
*/ */
public class BaseRegion implements Region { public class BaseRegion implements Region {
protected final Map cache = new ConcurrentHashMap(); private final CachingRegionFactory cachingRegionFactory;
private final String name; private final String name;
protected final Map cache = new ConcurrentHashMap();
private static int timeout = Timestamper.ONE_MS * 60000; //60s private static int timeout = Timestamper.ONE_MS * 60000; //60s
BaseRegion(String name) { BaseRegion(CachingRegionFactory cachingRegionFactory, String name) {
this.cachingRegionFactory = cachingRegionFactory;
this.name = name; this.name = name;
} }
@Override public CachingRegionFactory getRegionFactory() {
public boolean contains(Object key) { return cachingRegionFactory;
return key != null ? cache.containsKey( key ) : false;
} }
@Override @Override
@ -35,6 +37,11 @@ public class BaseRegion implements Region {
return name; return name;
} }
@Override
public boolean contains(Object key) {
return key != null ? cache.containsKey( key ) : false;
}
@Override @Override
public void destroy() throws CacheException { public void destroy() throws CacheException {
cache.clear(); cache.clear();

View File

@ -15,8 +15,8 @@ import org.hibernate.cache.spi.TransactionalDataRegion;
class BaseTransactionalDataRegion extends BaseGeneralDataRegion implements TransactionalDataRegion { class BaseTransactionalDataRegion extends BaseGeneralDataRegion implements TransactionalDataRegion {
private final CacheDataDescription metadata; private final CacheDataDescription metadata;
BaseTransactionalDataRegion(String name, CacheDataDescription metadata) { BaseTransactionalDataRegion(CachingRegionFactory cachingRegionFactory, String name, CacheDataDescription metadata) {
super( name ); super( cachingRegionFactory, name );
this.metadata = metadata; this.metadata = metadata;
} }

View File

@ -10,7 +10,9 @@ import java.util.Properties;
import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException; import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.NaturalIdRegion;
@ -28,19 +30,34 @@ public class CachingRegionFactory implements RegionFactory {
private static final Logger LOG = Logger.getLogger( CachingRegionFactory.class.getName() ); private static final Logger LOG = Logger.getLogger( CachingRegionFactory.class.getName() );
public static String DEFAULT_ACCESSTYPE = "DefaultAccessType"; public static String DEFAULT_ACCESSTYPE = "DefaultAccessType";
private final CacheKeysFactory cacheKeysFactory;
private SessionFactoryOptions settings; private SessionFactoryOptions settings;
private Properties properties; private Properties properties;
public CachingRegionFactory() { public CachingRegionFactory() {
LOG.warn( "CachingRegionFactory should be only used for testing." ); this( DefaultCacheKeysFactory.INSTANCE, null );
}
public CachingRegionFactory(CacheKeysFactory cacheKeysFactory) {
this( cacheKeysFactory, null );
} }
public CachingRegionFactory(Properties properties) { public CachingRegionFactory(Properties properties) {
//add here to avoid run into catch this( DefaultCacheKeysFactory.INSTANCE, properties );
}
public CachingRegionFactory(CacheKeysFactory cacheKeysFactory, Properties properties) {
LOG.warn( "CachingRegionFactory should be only used for testing." ); LOG.warn( "CachingRegionFactory should be only used for testing." );
this.cacheKeysFactory = cacheKeysFactory;
this.properties = properties; this.properties = properties;
} }
public CacheKeysFactory getCacheKeysFactory() {
return cacheKeysFactory;
}
@Override @Override
public void start(SessionFactoryOptions settings, Properties properties) throws CacheException { public void start(SessionFactoryOptions settings, Properties properties) throws CacheException {
this.settings = settings; this.settings = settings;
@ -72,43 +89,42 @@ public class CachingRegionFactory implements RegionFactory {
@Override @Override
public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException { throws CacheException {
return new EntityRegionImpl( regionName, metadata, settings ); return new EntityRegionImpl( this, regionName, metadata, settings );
} }
@Override @Override
public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException { throws CacheException {
return new NaturalIdRegionImpl( regionName, metadata, settings ); return new NaturalIdRegionImpl( this, regionName, metadata, settings );
} }
@Override @Override
public CollectionRegion buildCollectionRegion( public CollectionRegion buildCollectionRegion(
String regionName, String regionName,
Properties properties, Properties properties,
CacheDataDescription metadata) CacheDataDescription metadata) throws CacheException {
throws CacheException { return new CollectionRegionImpl( this, regionName, metadata, settings );
return new CollectionRegionImpl( regionName, metadata, settings );
} }
@Override @Override
public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException { public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
return new QueryResultsRegionImpl( regionName ); return new QueryResultsRegionImpl( this, regionName );
} }
@Override @Override
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException { public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
return new TimestampsRegionImpl( regionName ); return new TimestampsRegionImpl( this, regionName );
} }
private static class QueryResultsRegionImpl extends BaseGeneralDataRegion implements QueryResultsRegion { private static class QueryResultsRegionImpl extends BaseGeneralDataRegion implements QueryResultsRegion {
QueryResultsRegionImpl(String name) { QueryResultsRegionImpl(CachingRegionFactory cachingRegionFactory, String name) {
super( name ); super( cachingRegionFactory, name );
} }
} }
private static class TimestampsRegionImpl extends BaseGeneralDataRegion implements TimestampsRegion { private static class TimestampsRegionImpl extends BaseGeneralDataRegion implements TimestampsRegion {
TimestampsRegionImpl(String name) { TimestampsRegionImpl(CachingRegionFactory cachingRegionFactory, String name) {
super( name ); super( cachingRegionFactory, name );
} }
} }
} }

View File

@ -23,8 +23,12 @@ class CollectionRegionImpl extends BaseTransactionalDataRegion implements Collec
private final SessionFactoryOptions settings; private final SessionFactoryOptions settings;
CollectionRegionImpl(String name, CacheDataDescription metadata, SessionFactoryOptions settings) { CollectionRegionImpl(
super( name, metadata ); CachingRegionFactory cachingRegionFactory,
String name,
CacheDataDescription metadata,
SessionFactoryOptions settings) {
super( cachingRegionFactory, name, metadata );
this.settings = settings; this.settings = settings;
} }

View File

@ -18,14 +18,17 @@ import org.jboss.logging.Logger;
/** /**
* @author Strong Liu * @author Strong Liu
*/ */
class EntityRegionImpl extends BaseTransactionalDataRegion implements EntityRegion { public class EntityRegionImpl extends BaseTransactionalDataRegion implements EntityRegion {
private static final Logger LOG = Logger.getLogger( EntityRegionImpl.class ); private static final Logger LOG = Logger.getLogger( EntityRegionImpl.class );
private final SessionFactoryOptions settings; private final SessionFactoryOptions settings;
EntityRegionImpl(String name, CacheDataDescription metadata, SessionFactoryOptions settings) { protected EntityRegionImpl(
super( name, metadata ); CachingRegionFactory cachingRegionFactory,
String name,
CacheDataDescription metadata,
SessionFactoryOptions settings) {
super( cachingRegionFactory, name, metadata );
this.settings = settings; this.settings = settings;
} }

View File

@ -23,8 +23,12 @@ class NaturalIdRegionImpl extends BaseTransactionalDataRegion implements Natural
private final SessionFactoryOptions settings; private final SessionFactoryOptions settings;
NaturalIdRegionImpl(String name, CacheDataDescription metadata, SessionFactoryOptions settings) { NaturalIdRegionImpl(
super( name, metadata ); CachingRegionFactory cachingRegionFactory,
String name,
CacheDataDescription metadata,
SessionFactoryOptions settings) {
super( cachingRegionFactory, name, metadata );
this.settings = settings; this.settings = settings;
} }

View File

@ -48,11 +48,11 @@ class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStr
@Override @Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); return region.getRegionFactory().getCacheKeysFactory().createCollectionKey( id, persister, factory, tenantIdentifier );
} }
@Override @Override
public Object getCacheKeyId(Object cacheKey) { public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.getCollectionId( cacheKey ); return region.getRegionFactory().getCacheKeysFactory().getCollectionId( cacheKey );
} }
} }

View File

@ -110,11 +110,11 @@ class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrateg
@Override @Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); return region.getRegionFactory().getCacheKeysFactory().createEntityKey( id, persister, factory, tenantIdentifier );
} }
@Override @Override
public Object getCacheKeyId(Object cacheKey) { public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.getEntityId( cacheKey ); return region.getRegionFactory().getCacheKeysFactory().getEntityId( cacheKey );
} }
} }

View File

@ -107,11 +107,11 @@ class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStra
@Override @Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) { public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); return region.getRegionFactory().getCacheKeysFactory().createNaturalIdKey( naturalIdValues, persister, session );
} }
@Override @Override
public Object[] getNaturalIdValues(Object cacheKey) { public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.getNaturalIdValues( cacheKey ); return region.getRegionFactory().getCacheKeysFactory().getNaturalIdValues( cacheKey );
} }
} }