diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java index 28610c21ef..b849330f39 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java @@ -11,6 +11,7 @@ import java.util.Comparator; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.mapping.Collection; import org.hibernate.mapping.PersistentClass; +import org.hibernate.type.Type; import org.hibernate.type.VersionType; /** @@ -22,19 +23,21 @@ public class CacheDataDescriptionImpl implements CacheDataDescription { private final boolean mutable; private final boolean versioned; private final Comparator versionComparator; + private final Type keyType; /** * Constructs a CacheDataDescriptionImpl instance. Generally speaking, code should use one of the * overloaded {@link #decode} methods rather than direct instantiation. - * * @param mutable Is the described data mutable? * @param versioned Is the described data versioned? * @param versionComparator The described data's version value comparator (if versioned). + * @param keyType */ - public CacheDataDescriptionImpl(boolean mutable, boolean versioned, Comparator versionComparator) { + public CacheDataDescriptionImpl(boolean mutable, boolean versioned, Comparator versionComparator, Type keyType) { this.mutable = mutable; this.versioned = versioned; this.versionComparator = versionComparator; + this.keyType = keyType; } @Override @@ -52,6 +55,11 @@ public class CacheDataDescriptionImpl implements CacheDataDescription { return versionComparator; } + @Override + public Type getKeyType() { + return keyType; + } + /** * Builds a CacheDataDescriptionImpl from the mapping model of an entity class. * @@ -65,8 +73,8 @@ public class CacheDataDescriptionImpl implements CacheDataDescription { model.isVersioned(), model.isVersioned() ? ( (VersionType) model.getVersion().getType() ).getComparator() - : null - ); + : null, + model.getIdentifierProperty().getType()); } /** @@ -82,8 +90,8 @@ public class CacheDataDescriptionImpl implements CacheDataDescription { model.getOwner().isVersioned(), model.getOwner().isVersioned() ? ( (VersionType) model.getOwner().getVersion().getType() ).getComparator() - : null - ); + : null, + model.getKey().getType()); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java index d70bca553e..15aa4c6ce4 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java @@ -6,6 +6,7 @@ */ package org.hibernate.cache.internal; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; @@ -48,7 +49,7 @@ public class DefaultCacheKeysFactory { } public static Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { - return new OldNaturalIdCacheKey( naturalIdValues, persister, session ); + return new OldNaturalIdCacheKey( naturalIdValues, persister.getPropertyTypes(), persister.getNaturalIdentifierProperties(), persister.getRootEntityName(), session ); } public static Object getEntityId(Object cacheKey) { @@ -62,4 +63,36 @@ public class DefaultCacheKeysFactory { public static Object[] getNaturalIdValues(Object cacheKey) { return ((OldNaturalIdCacheKey) cacheKey).getNaturalIdValues(); } + + public static CacheKeysFactory INSTANCE = new CacheKeysFactory() { + @Override + public Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey(id, persister, factory, tenantIdentifier); + } + + @Override + public Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier); + } + + @Override + public Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session); + } + + @Override + public Object getEntityId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } + + @Override + public Object getCollectionId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } + }; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java index 3cda420993..b05233a0f8 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java @@ -15,7 +15,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.internal.util.ValueHolder; import org.hibernate.internal.util.compare.EqualsHelper; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -41,24 +40,22 @@ public class OldNaturalIdCacheKey implements Serializable { /** * Construct a new key for a caching natural identifier resolutions into the second level cache. - * * @param naturalIdValues The naturalIdValues associated with the cached data - * @param persister The persister for the entity + * @param propertyTypes + * @param naturalIdPropertyIndexes * @param session The originating session */ public OldNaturalIdCacheKey( final Object[] naturalIdValues, - final EntityPersister persister, + Type[] propertyTypes, int[] naturalIdPropertyIndexes, final String entityName, final SessionImplementor session) { - this.entityName = persister.getRootEntityName(); + this.entityName = entityName; this.tenantId = session.getTenantIdentifier(); this.naturalIdValues = new Serializable[naturalIdValues.length]; final SessionFactoryImplementor factory = session.getFactory(); - final int[] naturalIdPropertyIndexes = persister.getNaturalIdentifierProperties(); - final Type[] propertyTypes = persister.getPropertyTypes(); final int prime = 31; int result = 1; @@ -93,7 +90,7 @@ public class OldNaturalIdCacheKey implements Serializable { public String initialize() { //Complex toString is needed as naturalIds for entities are not simply based on a single value like primary keys //the only same way to differentiate the keys is to included the disassembled values in the string. - final StringBuilder toStringBuilder = new StringBuilder( entityName ).append( "##NaturalId[" ); + final StringBuilder toStringBuilder = new StringBuilder().append( entityName ).append( "##NaturalId[" ); for ( int i = 0; i < naturalIdValues.length; i++ ) { toStringBuilder.append( naturalIdValues[i] ); if ( i + 1 < naturalIdValues.length ) { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java new file mode 100644 index 0000000000..d5dceaf0c6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java @@ -0,0 +1,54 @@ +/* + * 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 . + */ +package org.hibernate.cache.internal; + +import org.hibernate.cache.spi.CacheKeysFactory; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; + +/** + * Factory that does not fill in the entityName or role + * + * @author Radim Vansa <rvansa@redhat.com> + */ +public class SimpleCacheKeysFactory implements CacheKeysFactory { + +public static CacheKeysFactory INSTANCE = new SimpleCacheKeysFactory(); + + @Override + public Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return id; + } + + @Override + public Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return id; + } + + @Override + public Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + // natural ids always need to be wrapped + return new OldNaturalIdCacheKey(naturalIdValues, persister.getPropertyTypes(), persister.getNaturalIdentifierProperties(), null, session); + } + + @Override + public Object getEntityId(Object cacheKey) { + return cacheKey; + } + + @Override + public Object getCollectionId(Object cacheKey) { + return cacheKey; + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return ((OldNaturalIdCacheKey) cacheKey).getNaturalIdValues(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheDataDescription.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheDataDescription.java index 70b7758238..eeecaaf969 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheDataDescription.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheDataDescription.java @@ -8,6 +8,8 @@ package org.hibernate.cache.spi; import java.util.Comparator; +import org.hibernate.type.Type; + /** * Describes attributes regarding the type of data to be cached. * @@ -37,4 +39,10 @@ public interface CacheDataDescription { * @return The comparator for versions, or {@code null} */ public Comparator getVersionComparator(); + + /** + * @return Type of the key that will be used as the key in the cache, or {@code null} if the natural comparison + * ({@link Object#hashCode()} and {@link Object#equals(Object)} methods should be used. + */ + Type getKeyType(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java new file mode 100644 index 0000000000..cc864b7506 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java @@ -0,0 +1,29 @@ +/* + * 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 . + */ +package org.hibernate.cache.spi; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; + +/** + * @author Radim Vansa <rvansa@redhat.com> + */ +public interface CacheKeysFactory { + Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier); + + Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier); + + Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session); + + Object getEntityId(Object cacheKey); + + Object getCollectionId(Object cacheKey); + + Object[] getNaturalIdValues(Object cacheKey); +} diff --git a/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java b/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java index 9143c57f20..8cc1ef75c2 100644 --- a/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java @@ -62,7 +62,7 @@ public class NaturalIdCacheKeyTest { }); final OldNaturalIdCacheKey key = (OldNaturalIdCacheKey) DefaultCacheKeysFactory.createNaturalIdKey( new Object[] {"a", "b", "c"}, entityPersister, sessionImplementor ); - + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(key); diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java index 044518c4bd..32042ed4e2 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java @@ -20,6 +20,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import org.hibernate.MultiTenancyStrategy; import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.collection.CollectionRegionImpl; @@ -33,7 +34,10 @@ import org.hibernate.cache.infinispan.timestamp.TimestampsRegionImpl; import org.hibernate.cache.infinispan.tm.HibernateTransactionManagerLookup; import org.hibernate.cache.infinispan.util.CacheCommandFactory; import org.hibernate.cache.infinispan.util.Caches; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.internal.SimpleCacheKeysFactory; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.NaturalIdRegion; @@ -217,6 +221,7 @@ public class InfinispanRegionFactory implements RegionFactory { private org.infinispan.transaction.lookup.TransactionManagerLookup transactionManagerlookup; private List regionNames = new ArrayList(); + private SessionFactoryOptions settings; /** * Create a new instance using the default configuration. @@ -241,8 +246,8 @@ public class InfinispanRegionFactory implements RegionFactory { if ( log.isDebugEnabled() ) { log.debug( "Building collection cache region [" + regionName + "]" ); } - final AdvancedCache cache = getCache( regionName, COLLECTION_KEY, properties ); - final CollectionRegionImpl region = new CollectionRegionImpl( cache, regionName, metadata, this ); + final AdvancedCache cache = getCache( regionName, COLLECTION_KEY, properties, metadata); + final CollectionRegionImpl region = new CollectionRegionImpl( cache, regionName, metadata, this, buildCacheKeysFactory() ); startRegion( region, regionName ); return region; } @@ -258,8 +263,8 @@ public class InfinispanRegionFactory implements RegionFactory { metadata.isVersioned() ); } - final AdvancedCache cache = getCache( regionName, metadata.isMutable() ? ENTITY_KEY : IMMUTABLE_ENTITY_KEY, properties ); - final EntityRegionImpl region = new EntityRegionImpl( cache, regionName, metadata, this ); + final AdvancedCache cache = getCache( regionName, metadata.isMutable() ? ENTITY_KEY : IMMUTABLE_ENTITY_KEY, properties, metadata ); + final EntityRegionImpl region = new EntityRegionImpl( cache, regionName, metadata, this, buildCacheKeysFactory() ); startRegion( region, regionName ); return region; } @@ -268,10 +273,10 @@ public class InfinispanRegionFactory implements RegionFactory { public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException { if ( log.isDebugEnabled() ) { - log.debug( "Building natural id cache region [" + regionName + "]" ); + log.debug("Building natural id cache region [" + regionName + "]"); } - final AdvancedCache cache = getCache( regionName, NATURAL_ID_KEY, properties ); - final NaturalIdRegionImpl region = new NaturalIdRegionImpl( cache, regionName, metadata, this ); + final AdvancedCache cache = getCache( regionName, NATURAL_ID_KEY, properties, metadata); + final NaturalIdRegionImpl region = new NaturalIdRegionImpl( cache, regionName, metadata, this, buildCacheKeysFactory()); startRegion( region, regionName ); return region; } @@ -288,7 +293,7 @@ public class InfinispanRegionFactory implements RegionFactory { cacheName = regionName; } - final AdvancedCache cache = getCache( cacheName, QUERY_KEY, properties ); + final AdvancedCache cache = getCache( cacheName, QUERY_KEY, properties, null); final QueryResultsRegionImpl region = new QueryResultsRegionImpl( cache, regionName, this ); startRegion( region, regionName ); return region; @@ -300,7 +305,7 @@ public class InfinispanRegionFactory implements RegionFactory { if ( log.isDebugEnabled() ) { log.debug( "Building timestamps cache region [" + regionName + "]" ); } - final AdvancedCache cache = getCache( regionName, TIMESTAMPS_KEY, properties ); + final AdvancedCache cache = getCache( regionName, TIMESTAMPS_KEY, properties, null); final TimestampsRegionImpl region = createTimestampsRegion( cache, regionName ); startRegion( region, regionName ); return region; @@ -308,7 +313,7 @@ public class InfinispanRegionFactory implements RegionFactory { protected TimestampsRegionImpl createTimestampsRegion( AdvancedCache cache, String regionName) { - if ( Caches.isClustered( cache ) ) { + if ( Caches.isClustered(cache) ) { return new ClusteredTimestampsRegionImpl( cache, regionName, this ); } else { @@ -316,6 +321,15 @@ public class InfinispanRegionFactory implements RegionFactory { } } + private CacheKeysFactory buildCacheKeysFactory() { + if (settings.getMultiTenancyStrategy() != MultiTenancyStrategy.NONE) { + return DefaultCacheKeysFactory.INSTANCE; + } + else { + return SimpleCacheKeysFactory.INSTANCE; + } + } + @Override public boolean isMinimalPutsEnabledByDefault() { return true; @@ -345,6 +359,7 @@ public class InfinispanRegionFactory implements RegionFactory { try { transactionManagerlookup = createTransactionManagerLookup( settings, properties ); manager = createCacheManager( properties, settings.getServiceRegistry() ); + this.settings = settings; initGenericDataTypeOverrides(); final Enumeration keys = properties.propertyNames(); while ( keys.hasMoreElements() ) { @@ -587,7 +602,7 @@ public class InfinispanRegionFactory implements RegionFactory { } } - private AdvancedCache getCache(String regionName, String typeKey, Properties properties) { + private AdvancedCache getCache(String regionName, String typeKey, Properties properties, CacheDataDescription metadata) { TypeOverrides regionOverride = typeOverrides.get( regionName ); if ( !definedConfigurations.contains( regionName ) ) { final String templateCacheName; @@ -621,6 +636,13 @@ public class InfinispanRegionFactory implements RegionFactory { // Apply overrides typeOverrides.get( typeKey ).applyTo( builder ); } + // with multi-tenancy the keys will be wrapped + if (settings.getMultiTenancyStrategy() == MultiTenancyStrategy.NONE) { + // the keys may not define hashCode/equals correctly (e.g. arrays) + if (metadata != null && metadata.getKeyType() != null) { + builder.dataContainer().keyEquivalence(new TypeEquivalance(metadata.getKeyType())); + } + } // Configure transaction manager configureTransactionManager( builder, templateCacheName, properties ); // Define configuration diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/TypeEquivalance.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/TypeEquivalance.java new file mode 100644 index 0000000000..b87c92ae3d --- /dev/null +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/TypeEquivalance.java @@ -0,0 +1,46 @@ +/* + * 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 . + */ +package org.hibernate.cache.infinispan; + +import org.hibernate.type.Type; +import org.infinispan.commons.equivalence.Equivalence; + +/** + * @author Radim Vansa <rvansa@redhat.com> + */ +public class TypeEquivalance implements Equivalence { + private final Type type; + + public TypeEquivalance(Type type) { + this.type = type; + } + + @Override + public int hashCode(Object o) { + return type.getHashCode(o); + } + + @Override + public boolean equals(Object x, Object y) { + return type.isEqual(x, y); + } + + @Override + public String toString(Object o) { + return String.valueOf(o); + } + + @Override + public boolean isComparable(Object o) { + return true; // cannot guess from the type + } + + @Override + public int compare(Object x, Object y) { + return type.compare(x, y); + } +} diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java index 9ab7ac0653..69edd85bbf 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java @@ -6,6 +6,9 @@ */ package org.hibernate.cache.infinispan.access; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -15,14 +18,12 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; - import org.infinispan.AdvancedCache; +import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.manager.EmbeddedCacheManager; /** @@ -130,27 +131,37 @@ public class PutFromLoadValidator { public PutFromLoadValidator( AdvancedCache cache, long nakedPutInvalidationPeriod) { - this( - cache.getCacheManager(), cache.getTransactionManager(), + this(cache, cache.getCacheManager(), cache.getTransactionManager(), nakedPutInvalidationPeriod ); } /** * Creates a new put from load validator instance. - * - * @param cacheManager where to find a cache to store pending put information - * @param tm transaction manager - * @param nakedPutInvalidationPeriod Period (in ms) after a removal during which a call to - * {@link #acquirePutFromLoadLock(Object)} that hasn't been - * {@link #registerPendingPut(Object) pre-registered} (aka a "naked put") - * will return false. - */ - public PutFromLoadValidator( + * + * @param cache Cache instance on which to store pending put information. + * @param cacheManager where to find a cache to store pending put information + * @param tm transaction manager + * @param nakedPutInvalidationPeriod Period (in ms) after a removal during which a call to + * {@link #acquirePutFromLoadLock(Object)} that hasn't been + * {@link #registerPendingPut(Object) pre-registered} (aka a "naked put") + * will return false. + */ + public PutFromLoadValidator(AdvancedCache cache, EmbeddedCacheManager cacheManager, TransactionManager tm, long nakedPutInvalidationPeriod) { - this.pendingPuts = cacheManager - .getCache( InfinispanRegionFactory.PENDING_PUTS_CACHE_NAME ); + + Configuration cacheConfiguration = cache.getCacheConfiguration(); + Configuration pendingPutsConfiguration = cacheManager.getCacheConfiguration(InfinispanRegionFactory.PENDING_PUTS_CACHE_NAME); + ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); + if (pendingPutsConfiguration != null) { + configurationBuilder.read(pendingPutsConfiguration); + } + configurationBuilder.dataContainer().keyEquivalence(cacheConfiguration.dataContainer().keyEquivalence()); + String pendingPutsName = cache.getName() + "-" + InfinispanRegionFactory.PENDING_PUTS_CACHE_NAME; + cacheManager.defineConfiguration(pendingPutsName, configurationBuilder.build()); + + this.pendingPuts = cacheManager.getCache(pendingPutsName); this.transactionManager = tm; this.nakedPutInvalidationPeriod = nakedPutInvalidationPeriod; } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java index 0150e7954a..869c6bef24 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java @@ -10,11 +10,11 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; - import org.infinispan.AdvancedCache; /** @@ -33,11 +33,12 @@ public class CollectionRegionImpl extends BaseTransactionalDataRegion implements * @param name of collection type * @param metadata for the collection type * @param factory for the region + * @param cacheKeysFactory factory for cache keys */ public CollectionRegionImpl( AdvancedCache cache, String name, - CacheDataDescription metadata, RegionFactory factory) { - super( cache, name, metadata, factory ); + CacheDataDescription metadata, RegionFactory factory, CacheKeysFactory cacheKeysFactory) { + super( cache, name, metadata, factory, cacheKeysFactory ); } @Override diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java index a72a093c01..3c49f91153 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java @@ -8,7 +8,6 @@ package org.hibernate.cache.infinispan.collection; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; -import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -82,12 +81,12 @@ class TransactionalAccess implements CollectionRegionAccessStrategy { @Override public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { - return DefaultCacheKeysFactory.createCollectionKey(id, persister, factory, tenantIdentifier); + return region.getCacheKeysFactory().createCollectionKey(id, persister, factory, tenantIdentifier); } @Override public Object getCacheKeyId(Object cacheKey) { - return DefaultCacheKeysFactory.getCollectionId(cacheKey); + return region.getCacheKeysFactory().getCollectionId(cacheKey); } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java index f81a642211..1cc5215a54 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java @@ -10,6 +10,7 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.access.AccessType; @@ -33,11 +34,12 @@ public class EntityRegionImpl extends BaseTransactionalDataRegion implements Ent * @param name of entity type * @param metadata for the entity type * @param factory for the region + * @param cacheKeysFactory factory for cache keys */ public EntityRegionImpl( AdvancedCache cache, String name, - CacheDataDescription metadata, RegionFactory factory) { - super( cache, name, metadata, factory ); + CacheDataDescription metadata, RegionFactory factory, CacheKeysFactory cacheKeysFactory) { + super( cache, name, metadata, factory, cacheKeysFactory); } @Override @@ -60,5 +62,4 @@ public class EntityRegionImpl extends BaseTransactionalDataRegion implements Ent public PutFromLoadValidator getPutFromLoadValidator() { return new PutFromLoadValidator( cache ); } - } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java index 15f408144d..e24e5e4147 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java @@ -8,7 +8,6 @@ package org.hibernate.cache.infinispan.entity; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; -import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -100,11 +99,11 @@ class TransactionalAccess implements EntityRegionAccessStrategy { @Override public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { - return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier); + return region.getCacheKeysFactory().createEntityKey(id, persister, factory, tenantIdentifier); } @Override public Object getCacheKeyId(Object cacheKey) { - return DefaultCacheKeysFactory.getEntityId(cacheKey); + return region.getCacheKeysFactory().getEntityId(cacheKey); } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java index e9746b4d02..06a81dba02 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java @@ -7,6 +7,7 @@ package org.hibernate.cache.infinispan.impl; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; @@ -23,6 +24,7 @@ public abstract class BaseTransactionalDataRegion extends BaseRegion implements TransactionalDataRegion { private final CacheDataDescription metadata; + private final CacheKeysFactory cacheKeysFactory; /** * Base transactional region constructor @@ -31,12 +33,14 @@ public abstract class BaseTransactionalDataRegion * @param name of the transactional region * @param metadata for the transactional region * @param factory for the transactional region + * @param cacheKeysFactory factory for cache keys */ public BaseTransactionalDataRegion( AdvancedCache cache, String name, - CacheDataDescription metadata, RegionFactory factory) { - super( cache, name, factory ); + CacheDataDescription metadata, RegionFactory factory, CacheKeysFactory cacheKeysFactory) { + super( cache, name, factory); this.metadata = metadata; + this.cacheKeysFactory = cacheKeysFactory; } @Override @@ -44,4 +48,7 @@ public abstract class BaseTransactionalDataRegion return metadata; } + public CacheKeysFactory getCacheKeysFactory() { + return cacheKeysFactory; + } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java index 89c1f5e19b..3c7b6d82f4 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java @@ -10,11 +10,11 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; - import org.infinispan.AdvancedCache; /** @@ -33,11 +33,12 @@ public class NaturalIdRegionImpl extends BaseTransactionalDataRegion * @param name of natural id region * @param metadata for the natural id region * @param factory for the natural id region + * @param cacheKeysFactory factory for cache keys */ public NaturalIdRegionImpl( AdvancedCache cache, String name, - CacheDataDescription metadata, RegionFactory factory) { - super( cache, name, metadata, factory ); + CacheDataDescription metadata, RegionFactory factory, CacheKeysFactory cacheKeysFactory) { + super( cache, name, metadata, factory, cacheKeysFactory ); } @Override diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/TransactionalAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/TransactionalAccess.java index 8817b39e34..41706f6a3a 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/TransactionalAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/TransactionalAccess.java @@ -8,7 +8,6 @@ package org.hibernate.cache.infinispan.naturalid; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; -import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -108,11 +107,11 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy { @Override public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { - return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + return region.getCacheKeysFactory().createNaturalIdKey(naturalIdValues, persister, session); } @Override public Object[] getNaturalIdValues(Object cacheKey) { - return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + return region.getCacheKeysFactory().getNaturalIdValues(cacheKey); } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java index cbbf0b1449..a5c2eb3f96 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java @@ -13,7 +13,6 @@ import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion; import org.hibernate.cache.infinispan.util.Caches; import org.hibernate.cache.spi.QueryResultsRegion; import org.hibernate.cache.spi.RegionFactory; - import org.infinispan.AdvancedCache; import org.infinispan.context.Flag; @@ -38,7 +37,7 @@ public class QueryResultsRegionImpl extends BaseTransactionalDataRegion implemen * @param factory for the query region */ public QueryResultsRegionImpl(AdvancedCache cache, String name, RegionFactory factory) { - super( cache, name, null, factory ); + super( cache, name, null, factory, null ); // If Infinispan is using INVALIDATION for query cache, we don't want to propagate changes. // We use the Timestamps cache to manage invalidation final boolean localOnly = Caches.isInvalidationCache( cache ); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java index b08b0718e8..d8b84bf9fe 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java @@ -11,10 +11,12 @@ import java.util.Properties; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; +import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; import org.hibernate.cache.spi.access.AccessType; +import org.hibernate.internal.util.compare.ComparableComparator; import org.hibernate.test.cache.infinispan.util.CacheTestUtil; import org.junit.Test; @@ -29,6 +31,8 @@ import static org.junit.Assert.assertTrue; * @since 3.5 */ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractRegionImplTestCase { + protected static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, ComparableComparator.INSTANCE, null); + @Test public void testSupportedAccessTypes() throws Exception { supportedAccessTypeTest(); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java index 0d29223a3b..210a751b53 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java @@ -133,11 +133,11 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm } protected void regionEvict(GeneralDataRegion region) throws Exception { - region.evict(KEY); + region.evict(KEY); } protected void regionPut(GeneralDataRegion region) throws Exception { - region.put(KEY, VALUE1); + region.put(KEY, VALUE1); } protected abstract String getStandardRegionName(String regionPrefix); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java index 2daf5ad2e0..57c3198b7f 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java @@ -32,7 +32,7 @@ public abstract class AbstractRegionImplTestCase extends AbstractNonFunctionalTe protected abstract void removeFromRegion(Region region, Object key); protected CacheDataDescription getCacheDataDescription() { - return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE); + return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE, null); } } diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java index be691cf975..b5b6bc1d4c 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java @@ -56,8 +56,8 @@ import static org.junit.Assert.fail; * @since 3.5 */ public class InfinispanRegionFactoryTestCase { - private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); - private static CacheDataDescription IMMUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(false, false, null); + private static final CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null, null); + private static final CacheDataDescription IMMUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(false, false, null, null); @Test public void testConfigurationProcessing() { diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java index de2b93b3b2..066b118470 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java @@ -6,6 +6,7 @@ */ package org.hibernate.test.cache.infinispan.access; +import javax.transaction.TransactionManager; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; @@ -15,20 +16,18 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import javax.transaction.TransactionManager; import org.hibernate.cache.infinispan.access.PutFromLoadValidator; - import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - +import org.infinispan.AdvancedCache; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.CacheManagerCallable; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import static org.infinispan.test.TestingUtil.withCacheManager; import static org.junit.Assert.assertEquals; @@ -84,7 +83,7 @@ public class PutFromLoadValidatorUnitTestCase { @Override public void call() { try { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); if (transactional) { @@ -119,7 +118,7 @@ public class PutFromLoadValidatorUnitTestCase { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); try { @@ -166,7 +165,7 @@ public class PutFromLoadValidatorUnitTestCase { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); if (removeRegion) { @@ -218,7 +217,7 @@ public class PutFromLoadValidatorUnitTestCase { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); if (removeRegion) { @@ -272,7 +271,7 @@ public class PutFromLoadValidatorUnitTestCase { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); try { @@ -325,7 +324,7 @@ public class PutFromLoadValidatorUnitTestCase { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new TestValidator(cm, + PutFromLoadValidator testee = new TestValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, 100); if (removeRegion) { testee.invalidateRegion(); @@ -368,7 +367,7 @@ public class PutFromLoadValidatorUnitTestCase { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - final PutFromLoadValidator testee = new PutFromLoadValidator(cm, + final PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); @@ -440,8 +439,8 @@ public class PutFromLoadValidatorUnitTestCase { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - final PutFromLoadValidator testee = new PutFromLoadValidator( - cm, null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); + final PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), + cm, null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); final CountDownLatch removeLatch = new CountDownLatch(1); final CountDownLatch pferLatch = new CountDownLatch(1); final AtomicReference cache = new AtomicReference("INITIAL"); @@ -503,10 +502,10 @@ public class PutFromLoadValidatorUnitTestCase { private static class TestValidator extends PutFromLoadValidator { - protected TestValidator(EmbeddedCacheManager cm, + protected TestValidator(AdvancedCache cache, EmbeddedCacheManager cm, TransactionManager transactionManager, long nakedPutInvalidationPeriod) { - super(cm, transactionManager, nakedPutInvalidationPeriod); + super(cache, cm, transactionManager, nakedPutInvalidationPeriod); } @Override diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java index 1d85372e99..af8aedf97b 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java @@ -115,7 +115,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs } protected CacheDataDescription getCacheDataDescription() { - return new CacheDataDescriptionImpl( true, true, ComparableComparator.INSTANCE ); + return new CacheDataDescriptionImpl( true, true, ComparableComparator.INSTANCE, null); } @After @@ -152,7 +152,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs withCacheManager(new CacheManagerCallable(TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator validator = new PutFromLoadValidator(cm, + PutFromLoadValidator validator = new PutFromLoadValidator(remoteCollectionRegion.getCache(), cm, remoteTm, 20000) { @Override public boolean acquirePutFromLoadLock(Object key) { diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java index a26b2581cd..6b96a69999 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java @@ -10,7 +10,6 @@ import java.util.Properties; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; -import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.Region; @@ -29,9 +28,6 @@ import static org.junit.Assert.fail; * @author Galder ZamarreƱo */ public class CollectionRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { - - private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); - @Override protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties properties) { CollectionRegion region = regionFactory.buildCollectionRegion("test", properties, MUTABLE_NON_VERSIONED); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java index 61503cb1ff..07e5948452 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java @@ -8,9 +8,12 @@ package org.hibernate.test.cache.infinispan.collection; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; +import org.hibernate.cache.internal.CacheDataDescriptionImpl; +import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; +import org.hibernate.internal.util.compare.ComparableComparator; import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase; import org.hibernate.test.cache.infinispan.NodeEnvironment; import org.hibernate.test.cache.infinispan.util.CacheTestUtil; @@ -31,8 +34,8 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase public static final String REGION_NAME = "test/com.foo.test"; public static final Object KEY = TestingKeyFactory.generateCollectionCacheKey( "KEY" ); - public static final String VALUE1 = "VALUE1"; - public static final String VALUE2 = "VALUE2"; + public static final CacheDataDescription CACHE_DATA_DESCRIPTION + = new CacheDataDescriptionImpl(false, false, ComparableComparator.INSTANCE, null); private NodeEnvironment environment; private static CollectionRegionAccessStrategy accessStrategy; @@ -45,7 +48,7 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase // Sleep a bit to avoid concurrent FLUSH problem avoidConcurrentFlush(); - accessStrategy = environment.getCollectionRegion( REGION_NAME, null ).buildAccessStrategy( getAccessType() ); + accessStrategy = environment.getCollectionRegion( REGION_NAME, CACHE_DATA_DESCRIPTION).buildAccessStrategy( getAccessType() ); } protected StandardServiceRegistryBuilder createStandardServiceRegistryBuilder() { diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java index da336ff0d9..0eab81e6ba 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java @@ -115,7 +115,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac } protected CacheDataDescription getCacheDataDescription() { - return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE); + return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE, null); } @After diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java index 2752a41507..645bc5a250 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java @@ -10,7 +10,6 @@ import java.util.Properties; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; -import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.Region; @@ -30,8 +29,6 @@ import static org.junit.Assert.fail; */ public class EntityRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { - private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); - @Override protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties properties) { EntityRegion region = regionFactory.buildEntityRegion("test", properties, MUTABLE_NON_VERSIONED); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java index 61fb89aa3e..18ca82ebd6 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java @@ -12,6 +12,7 @@ import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; +import org.hibernate.internal.util.compare.ComparableComparator; import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase; import org.hibernate.test.cache.infinispan.NodeEnvironment; import org.hibernate.test.cache.infinispan.util.CacheTestUtil; @@ -38,6 +39,8 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase public static final Object KEY = TestingKeyFactory.generateEntityCacheKey( "KEY" ); public static final String VALUE1 = "VALUE1"; public static final String VALUE2 = "VALUE2"; + protected static final CacheDataDescriptionImpl CACHE_DATA_DESCRIPTION + = new CacheDataDescriptionImpl(true, false, ComparableComparator.INSTANCE, null); private NodeEnvironment environment; private EntityRegionAccessStrategy accessStrategy; @@ -50,7 +53,7 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase // Sleep a bit to avoid concurrent FLUSH problem avoidConcurrentFlush(); - accessStrategy = environment.getEntityRegion( REGION_NAME, new CacheDataDescriptionImpl(true, false, null)).buildAccessStrategy( getAccessType() ); + accessStrategy = environment.getEntityRegion( REGION_NAME, CACHE_DATA_DESCRIPTION).buildAccessStrategy( getAccessType() ); } protected StandardServiceRegistryBuilder createStandardServiceRegistryBuilder() { diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/EqualityTest.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/EqualityTest.java new file mode 100644 index 0000000000..6046c331bc --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/EqualityTest.java @@ -0,0 +1,77 @@ +package org.hibernate.test.cache.infinispan.functional; + +import java.util.concurrent.Callable; + +import org.hibernate.Session; +import org.hibernate.stat.Statistics; +import org.junit.Test; + +import static org.infinispan.test.TestingUtil.withTx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * Persons should be correctly indexed since we can use Type for comparison + * + * @author Radim Vansa <rvansa@redhat.com> + */ +public class EqualityTest extends SingleNodeTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Person.class }; + } + + @Test + public void testEqualityFromType() throws Exception { + Person john = new Person("John", "Black", 26); + Person peter = new Person("Peter", "White", 32); + + withTx(tm, new Callable() { + @Override + public Void call() throws Exception { + Session session = openSession(); + session.getTransaction().begin(); + session.persist(john); + session.persist(peter); + session.getTransaction().commit(); + session.close(); + return null; + } + }); + + Statistics statistics = sessionFactory().getStatistics(); + statistics.clear(); + + for (int i = 0; i < 5; ++i) { + withTx(tm, new Callable() { + @Override + public Void call() throws Exception { + Session session = openSession(); + session.getTransaction().begin(); + Person p1 = session.get(Person.class, john.name); + assertPersonEquals(john, p1); + Person p2 = session.get(Person.class, peter.name); + assertPersonEquals(peter, p2); + Person p3 = session.get(Person.class, new Name("Foo", "Bar")); + assertNull(p3); + session.getTransaction().commit(); + session.close(); + return null; + } + }); + } + + assertTrue(statistics.getSecondLevelCacheHitCount() > 0); + assertTrue(statistics.getSecondLevelCacheMissCount() > 0); + } + + private static void assertPersonEquals(Person expected, Person person) { + assertNotNull(person); + assertNotNull(person.getName()); + assertEquals(expected.getName().getFirstName(), person.getName().getFirstName()); + assertEquals(expected.getName().getLastName(), person.getName().getLastName()); + assertEquals(expected.getAge(), person.getAge()); + } +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java new file mode 100644 index 0000000000..c2f2eab6d1 --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java @@ -0,0 +1,118 @@ +package org.hibernate.test.cache.infinispan.functional; + +import java.util.concurrent.Callable; + +import org.hibernate.MultiTenancyStrategy; +import org.hibernate.Session; +import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cache.infinispan.entity.EntityRegionImpl; +import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider; +import org.hibernate.test.cache.infinispan.tm.XaConnectionProvider; +import org.hibernate.testing.env.ConnectionProviderBuilder; +import org.infinispan.commons.util.CloseableIteratorSet; +import org.infinispan.context.Flag; +import org.junit.Test; + +import static org.infinispan.test.TestingUtil.withTx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Radim Vansa <rvansa@redhat.com> + */ +public class MultiTenancyTestCase extends SingleNodeTestCase { + + private static final String DB1 = "db1"; + private static final String DB2 = "db2"; + private final ConnectionProvider db1 + = new XaConnectionProvider(ConnectionProviderBuilder.buildConnectionProvider(DB1)); + private final ConnectionProvider db2 + = new XaConnectionProvider(ConnectionProviderBuilder.buildConnectionProvider(DB2)); + + @Override + protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) { + super.configureStandardServiceRegistryBuilder(ssrb); + ssrb.addService(MultiTenantConnectionProvider.class, new AbstractMultiTenantConnectionProvider() { + + @Override + protected ConnectionProvider getAnyConnectionProvider() { + return db1; + } + + @Override + protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) { + if (DB1.equals(tenantIdentifier)) return db1; + if (DB2.equals(tenantIdentifier)) return db2; + throw new IllegalArgumentException(); + } + }); + } + + @Override + protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) { + super.configureSessionFactoryBuilder(sfb); + sfb.applyMultiTenancyStrategy(MultiTenancyStrategy.DATABASE); + } + + @Override + protected void cleanupTest() throws Exception { + db1.getConnection().close(); + db2.getConnection().close(); + } + + @Test + public void testMultiTenancy() throws Exception { + final Item item = new Item("my item", "description" ); + + long id = withTx(tm, new Callable() { + @Override + public Long call() throws Exception { + Session s = sessionFactory().withOptions().tenantIdentifier(DB1).openSession(); + s.getTransaction().begin(); + s.persist(item); + s.getTransaction().commit(); + s.close(); + return item.getId(); + } + }); + for (int i = 0; i < 5; ++i) { // make sure we get something cached + withTx(tm, new Callable() { + @Override + public Void call() throws Exception { + Session s = sessionFactory().withOptions().tenantIdentifier(DB1).openSession(); + s.getTransaction().begin(); + Item item2 = s.get(Item.class, id); + s.getTransaction().commit(); + s.close(); + assertNotNull(item2); + assertEquals(item.getName(), item2.getName()); + return null; + } + }); + + } + // The table ITEMS is not created in DB2 - we would get just an exception +// for (int i = 0; i < 5; ++i) { // make sure we get something cached +// withTx(tm, new Callable() { +// @Override +// public Void call() throws Exception { +// Session s = sessionFactory().withOptions().tenantIdentifier(DB2).openSession(); +// s.getTransaction().begin(); +// Item item2 = s.get(Item.class, id); +// s.getTransaction().commit(); +// s.close(); +// assertNull(item2); +// return null; +// } +// }); +// } + EntityRegionImpl region = (EntityRegionImpl) sessionFactory().getSecondLevelCacheRegion(Item.class.getName()); + CloseableIteratorSet keySet = region.getCache().withFlags(Flag.CACHE_MODE_LOCAL).keySet(); + assertEquals(1, keySet.size()); + assertEquals("OldCacheKeyImplementation", keySet.iterator().next().getClass().getSimpleName()); + } + +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Name.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Name.java new file mode 100644 index 0000000000..efc9996aca --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Name.java @@ -0,0 +1,48 @@ +package org.hibernate.test.cache.infinispan.functional; + +import javax.persistence.Embeddable; +import java.io.Serializable; + +/** + * Test class with incorrectly defined equals and hashCode. + * + * @author Radim Vansa <rvansa@redhat.com> + */ +@Embeddable +public class Name implements Serializable { + String firstName; + String lastName; + + public Name() {} + + public Name(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public boolean equals(Object obj) { + return false; + } +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/NoTenancyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/NoTenancyTestCase.java new file mode 100644 index 0000000000..e79541c36e --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/NoTenancyTestCase.java @@ -0,0 +1,56 @@ +package org.hibernate.test.cache.infinispan.functional; + +import java.util.concurrent.Callable; + +import org.hibernate.Session; +import org.hibernate.cache.infinispan.entity.EntityRegionImpl; +import org.infinispan.commons.util.CloseableIteratorSet; +import org.infinispan.context.Flag; +import org.junit.Test; + +import static org.infinispan.test.TestingUtil.withTx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Radim Vansa <rvansa@redhat.com> + */ +public class NoTenancyTestCase extends SingleNodeTestCase { + @Test + public void testNoTenancy() throws Exception { + final Item item = new Item("my item", "description" ); + + long id = withTx(tm, new Callable() { + @Override + public Long call() throws Exception { + Session s = openSession(); + s.getTransaction().begin(); + s.persist(item); + s.getTransaction().commit(); + s.close(); + return item.getId(); + } + }); + for (int i = 0; i < 5; ++i) { // make sure we get something cached + withTx(tm, new Callable() { + @Override + public Void call() throws Exception { + Session s = openSession(); + s.getTransaction().begin(); + Item item2 = s.get(Item.class, id); + s.getTransaction().commit(); + s.close(); + assertNotNull(item2); + assertEquals(item.getName(), item2.getName()); + return null; + } + }); + + } + EntityRegionImpl region = (EntityRegionImpl) sessionFactory().getSecondLevelCacheRegion(Item.class.getName()); + CloseableIteratorSet keySet = region.getCache().withFlags(Flag.CACHE_MODE_LOCAL).keySet(); + assertEquals(1, keySet.size()); + assertEquals(sessionFactory().getClassMetadata(Item.class).getIdentifierType().getReturnedClass(), keySet.iterator().next().getClass()); + } + +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Person.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Person.java new file mode 100644 index 0000000000..222525c4ff --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Person.java @@ -0,0 +1,41 @@ +package org.hibernate.test.cache.infinispan.functional; + +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import java.io.Serializable; + +/** + * Test class using EmbeddedId + * + * @author Radim Vansa <rvansa@redhat.com> + */ +@Entity +public class Person implements Serializable { + @EmbeddedId + Name name; + + int age; + + public Person() {} + + public Person(String firstName, String lastName, int age) { + name = new Name(firstName, lastName); + this.age = age; + } + + public Name getName() { + return name; + } + + public void setName(Name name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java index 2a8ba6baf0..782e144914 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java @@ -343,7 +343,7 @@ public class EntityCollectionInvalidationTestCase extends DualNodeTestCase { public void nodeVisited(CacheEntryVisitedEvent event) { log.debug( event.toString() ); if ( !event.isPre() ) { - String key = String.valueOf(event.getKey()); + String key = event.getCache().getName() + "#" + event.getKey(); log.debug( "MyListener[" + name + "] - Visiting key " + key ); // String name = fqn.toString(); String token = ".functional."; @@ -351,7 +351,7 @@ public class EntityCollectionInvalidationTestCase extends DualNodeTestCase { if ( index > -1 ) { index += token.length(); key = key.substring( index ); - log.debug( "MyListener[" + name + "] - recording visit to " + key ); + log.debug( "MyListener[" + this.name + "] - recording visit to " + key ); visited.add( key ); } } diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaConnectionProvider.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaConnectionProvider.java index 93074c5eaa..d44349d822 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaConnectionProvider.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaConnectionProvider.java @@ -23,10 +23,19 @@ import org.hibernate.testing.env.ConnectionProviderBuilder; * @since 3.5 */ public class XaConnectionProvider implements ConnectionProvider { - private static ConnectionProvider actualConnectionProvider = ConnectionProviderBuilder.buildConnectionProvider(); + private final static ConnectionProvider DEFAULT_CONNECTION_PROVIDER = ConnectionProviderBuilder.buildConnectionProvider(); + private final ConnectionProvider actualConnectionProvider; private boolean isTransactional; - public static ConnectionProvider getActualConnectionProvider() { + public XaConnectionProvider() { + this(DEFAULT_CONNECTION_PROVIDER); + } + + public XaConnectionProvider(ConnectionProvider connectionProvider) { + this.actualConnectionProvider = connectionProvider; + } + + public ConnectionProvider getActualConnectionProvider() { return actualConnectionProvider; }