diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java index dca84bbd78e9..eab59166400a 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java @@ -12,7 +12,7 @@ import org.hibernate.action.spi.BeforeTransactionCompletionProcess; import org.hibernate.action.spi.Executable; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionImplementor; @@ -76,12 +76,14 @@ public final void beforeExecutions() throws CacheException { // bidirectional association and it is one of the earlier entity actions which actually updates // the database (this action is responsible for second-level cache invalidation only) if ( persister.hasCache() ) { - final CacheKey ck = session.generateCacheKey( + final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( key, - persister.getKeyType(), - persister.getRole() + persister, + session.getFactory(), + session.getTenantIdentifier() ); - final SoftLock lock = persister.getCacheAccessStrategy().lockItem( ck, null ); + final SoftLock lock = cache.lockItem( ck, null ); // the old behavior used key as opposed to getKey() afterTransactionProcess = new CacheCleanupProcess( key, persister, lock ); } @@ -127,12 +129,14 @@ protected final SessionImplementor getSession() { protected final void evict() throws CacheException { if ( persister.hasCache() ) { - final CacheKey ck = session.generateCacheKey( + final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( key, - persister.getKeyType(), - persister.getRole() + persister, + session.getFactory(), + session.getTenantIdentifier() ); - persister.getCacheAccessStrategy().remove( ck ); + cache.remove( ck ); } } @@ -169,12 +173,14 @@ private CacheCleanupProcess(Serializable key, CollectionPersister persister, Sof @Override public void doAfterTransactionCompletion(boolean success, SessionImplementor session) { - final CacheKey ck = session.generateCacheKey( + final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( key, - persister.getKeyType(), - persister.getRole() + persister, + session.getFactory(), + session.getTenantIdentifier() ); - persister.getCacheAccessStrategy().unlockItem( ck, lock ); + cache.unlockItem( ck, lock ); } } @@ -191,8 +197,3 @@ protected EventSource eventSource() { } } - - - - - diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java index 27f32c00ac8e..2ac9736be879 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java @@ -10,7 +10,7 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.PersistenceContext; @@ -84,10 +84,11 @@ public void execute() throws HibernateException { version = persister.getVersion( instance ); } - final CacheKey ck; + final Object ck; if ( persister.hasCache() ) { - ck = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() ); - lock = persister.getCacheAccessStrategy().lockItem( ck, version ); + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + ck = cache.generateCacheKey( id, persister, session.getFactory(), session.getTenantIdentifier() ); + lock = cache.lockItem( ck, version ); } else { ck = null; @@ -184,13 +185,16 @@ private void postCommitDelete(boolean success) { @Override public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws HibernateException { - if ( getPersister().hasCache() ) { - final CacheKey ck = getSession().generateCacheKey( + EntityPersister entityPersister = getPersister(); + if ( entityPersister.hasCache() ) { + EntityRegionAccessStrategy cache = entityPersister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( getId(), - getPersister().getIdentifierType(), - getPersister().getRootEntityName() + entityPersister, + session.getFactory(), + session.getTenantIdentifier() ); - getPersister().getCacheAccessStrategy().unlockItem( ck, lock ); + cache.unlockItem( ck, lock ); } postCommitDelete( success ); } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java index c927873a69d2..8b64f155c3b0 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java @@ -10,11 +10,13 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.engine.internal.Versioning; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.PersistenceContext; +import org.hibernate.engine.spi.SessionEventListenerManager; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.event.service.spi.EventListenerGroup; @@ -85,8 +87,8 @@ public void execute() throws HibernateException { if ( !veto ) { persister.insert( id, getState(), instance, session ); - - final EntityEntry entry = session.getPersistenceContext().getEntry( instance ); + PersistenceContext persistenceContext = session.getPersistenceContext(); + final EntityEntry entry = persistenceContext.getEntry( instance ); if ( entry == null ) { throw new AssertionFailure( "possible non-threadsafe access to session" ); } @@ -101,10 +103,10 @@ public void execute() throws HibernateException { entry.postUpdate( instance, getState(), version ); } - getSession().getPersistenceContext().registerInsertedKey( getPersister(), getId() ); + persistenceContext.registerInsertedKey( persister, getId() ); } - final SessionFactoryImplementor factory = getSession().getFactory(); + final SessionFactoryImplementor factory = session.getFactory(); if ( isCachePutEnabled( persister, session ) ) { final CacheEntry ce = persister.buildCacheEntry( @@ -114,12 +116,13 @@ public void execute() throws HibernateException { session ); cacheEntry = persister.getCacheEntryStructure().structure( ce ); - final CacheKey ck = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() ); + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() ); final boolean put = cacheInsert( persister, ck ); if ( put && factory.getStatistics().isStatisticsEnabled() ) { - factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() ); + factory.getStatisticsImplementor().secondLevelCachePut( cache.getRegion().getName() ); } } @@ -134,7 +137,7 @@ public void execute() throws HibernateException { markExecuted(); } - private boolean cacheInsert(EntityPersister persister, CacheKey ck) { + private boolean cacheInsert(EntityPersister persister, Object ck) { try { getSession().getEventListenerManager().cachePutStart(); return persister.getCacheAccessStrategy().insert( ck, cacheEntry, version ); @@ -207,24 +210,27 @@ private boolean preInsert() { public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws HibernateException { final EntityPersister persister = getPersister(); if ( success && isCachePutEnabled( persister, getSession() ) ) { - final CacheKey ck = getSession().generateCacheKey( getId(), persister.getIdentifierType(), persister.getRootEntityName() ); - final boolean put = cacheAfterInsert( persister, ck ); - - if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) { - getSession().getFactory().getStatisticsImplementor() - .secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() ); + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + SessionFactoryImplementor sessionFactoryImplementor = session.getFactory(); + final Object ck = cache.generateCacheKey( getId(), persister, sessionFactoryImplementor, session.getTenantIdentifier() ); + final boolean put = cacheAfterInsert( cache, ck ); + + if ( put && sessionFactoryImplementor.getStatistics().isStatisticsEnabled() ) { + sessionFactoryImplementor.getStatisticsImplementor() + .secondLevelCachePut( cache.getRegion().getName() ); } } postCommitInsert( success ); } - private boolean cacheAfterInsert(EntityPersister persister, CacheKey ck) { + private boolean cacheAfterInsert(EntityRegionAccessStrategy cache, Object ck) { + final SessionEventListenerManager eventListenerManager = getSession().getEventListenerManager(); try { - getSession().getEventListenerManager().cachePutStart(); - return persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version ); + eventListenerManager.cachePutStart(); + return cache.afterInsert( ck, cacheEntry, version ); } finally { - getSession().getEventListenerManager().cachePutEnd(); + eventListenerManager.cachePutEnd(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java index 343d477db5ae..ea449655faa2 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java @@ -11,12 +11,13 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.engine.internal.Versioning; import org.hibernate.engine.spi.CachedNaturalIdValueSource; import org.hibernate.engine.spi.EntityEntry; +import org.hibernate.engine.spi.SessionEventListenerManager; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.Status; @@ -116,7 +117,7 @@ public void execute() throws HibernateException { final boolean veto = preUpdate(); - final SessionFactoryImplementor factory = getSession().getFactory(); + final SessionFactoryImplementor factory = session.getFactory(); Object previousVersion = this.previousVersion; if ( persister.isVersionPropertyGenerated() ) { // we need to grab the version value from the entity, otherwise @@ -125,14 +126,16 @@ public void execute() throws HibernateException { previousVersion = persister.getVersion( instance ); } - final CacheKey ck; + final Object ck; if ( persister.hasCache() ) { - ck = session.generateCacheKey( + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + ck = cache.generateCacheKey( id, - persister.getIdentifierType(), - persister.getRootEntityName() + persister, + factory, + session.getTenantIdentifier() ); - lock = persister.getCacheAccessStrategy().lockItem( ck, previousVersion ); + lock = cache.lockItem( ck, previousVersion ); } else { ck = null; @@ -152,7 +155,7 @@ public void execute() throws HibernateException { ); } - final EntityEntry entry = getSession().getPersistenceContext().getEntry( instance ); + final EntityEntry entry = session.getPersistenceContext().getEntry( instance ); if ( entry == null ) { throw new AssertionFailure( "possible nonthreadsafe access to session" ); } @@ -212,7 +215,7 @@ public void execute() throws HibernateException { } } - private boolean cacheUpdate(EntityPersister persister, Object previousVersion, CacheKey ck) { + private boolean cacheUpdate(EntityPersister persister, Object previousVersion, Object ck) { try { getSession().getEventListenerManager().cachePutStart(); return persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion ); @@ -307,34 +310,37 @@ protected boolean hasPostCommitEventListeners() { public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws CacheException { final EntityPersister persister = getPersister(); if ( persister.hasCache() ) { - - final CacheKey ck = getSession().generateCacheKey( + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( getId(), - persister.getIdentifierType(), - persister.getRootEntityName() + persister, + session.getFactory(), + session.getTenantIdentifier() + ); - + if ( success && cacheEntry!=null /*!persister.isCacheInvalidationRequired()*/ ) { - final boolean put = cacheAfterUpdate( persister, ck ); + final boolean put = cacheAfterUpdate( cache, ck ); if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) { - getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() ); + getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( cache.getRegion().getName() ); } } else { - persister.getCacheAccessStrategy().unlockItem( ck, lock ); + cache.unlockItem( ck, lock ); } } postCommitUpdate( success ); } - private boolean cacheAfterUpdate(EntityPersister persister, CacheKey ck) { + private boolean cacheAfterUpdate(EntityRegionAccessStrategy cache, Object ck) { + SessionEventListenerManager eventListenerManager = getSession().getEventListenerManager(); try { - getSession().getEventListenerManager().cachePutStart(); - return persister.getCacheAccessStrategy().afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock ); + eventListenerManager.cachePutStart(); + return cache.afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock ); } finally { - getSession().getEventListenerManager().cachePutEnd(); + eventListenerManager.cachePutEnd(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java index 6e52e1546609..773ce619e63f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java @@ -10,7 +10,7 @@ import java.util.Set; import org.hibernate.boot.Metadata; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventSource; @@ -136,8 +136,16 @@ private void evictCache(Object entity, EntityPersister persister, EventSource se } private void evict(Serializable id, CollectionPersister collectionPersister, EventSource session) { - LOG.debug( "Evict CollectionRegion " + collectionPersister.getRole() + " for id " + id ); - CacheKey key = session.generateCacheKey( id, collectionPersister.getKeyType(), collectionPersister.getRole() ); - collectionPersister.getCacheAccessStrategy().evict( key ); + if ( LOG.isDebugEnabled() ) { + LOG.debug( "Evict CollectionRegion " + collectionPersister.getRole() + " for id " + id ); + } + CollectionRegionAccessStrategy cache = collectionPersister.getCacheAccessStrategy(); + Object key = cache.generateCacheKey( + id, + collectionPersister, + session.getFactory(), + session.getTenantIdentifier() + ); + cache.evict( key ); } } 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 new file mode 100644 index 000000000000..d70bca553ee4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java @@ -0,0 +1,65 @@ +/* + * 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.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; + +/** + * Second level cache providers now have the option to use custom key implementations. + * This was done as the default key implementation is very generic and is quite + * a large object to allocate in large quantities at runtime. + * In some extreme cases, for example when the hit ratio is very low, this was making the efficiency + * penalty vs its benefits tradeoff questionable. + *

+ * Depending on configuration settings there might be opportunities to + * use simpler key implementations, for example when multi-tenancy is not being used to + * avoid the tenant identifier, or when a cache instance is entirely dedicated to a single type + * to use the primary id only, skipping the role or entity name. + *

+ * Even with multiple types sharing the same cache, their identifiers could be of the same + * {@link org.hibernate.type.Type}; in this case the cache container could + * use a single type reference to implement a custom equality function without having + * to look it up on each equality check: that's a small optimisation but the + * equality function is often invoked extremely frequently. + *

+ * Another reason is to make it more convenient to implement custom serialization protocols when the + * implementation supports clustering. + * + * @see org.hibernate.type.Type#getHashCode(Object, SessionFactoryImplementor) + * @see org.hibernate.type.Type#isEqual(Object, Object) + * @author Sanne Grinovero + * @since 5.0 + */ +public class DefaultCacheKeysFactory { + + public static Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return new OldCacheKeyImplementation( id, persister.getKeyType(), persister.getRole(), tenantIdentifier, factory ); + } + + public static Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return new OldCacheKeyImplementation( id, persister.getIdentifierType(), persister.getRootEntityName(), tenantIdentifier, factory ); + } + + public static Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return new OldNaturalIdCacheKey( naturalIdValues, persister, session ); + } + + public static Object getEntityId(Object cacheKey) { + return ((OldCacheKeyImplementation) cacheKey).getId(); + } + + public static Object getCollectionId(Object cacheKey) { + return ((OldCacheKeyImplementation) cacheKey).getId(); + } + + public static Object[] getNaturalIdValues(Object cacheKey) { + return ((OldNaturalIdCacheKey) cacheKey).getNaturalIdValues(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java old mode 100755 new mode 100644 similarity index 73% rename from hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java rename to hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java index f33d311af7ca..49b58da9f8e7 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java @@ -4,7 +4,7 @@ * 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; +package org.hibernate.cache.internal; import java.io.Serializable; @@ -16,11 +16,17 @@ * Allows multiple entity classes / collection roles to be stored in the same cache region. Also allows for composite * keys which do not properly implement equals()/hashCode(). * + * This was named org.hibernate.cache.spi.CacheKey in Hibernate until version 5. + * Temporarily maintained as a reference while all components catch up with the refactoring to the caching interfaces. + * * @author Gavin King * @author Steve Ebersole + * + * @deprecated In optimized implementations, wrapping the id is not necessary. */ -public class CacheKey implements Serializable { - private final Serializable key; +@Deprecated +final class OldCacheKeyImplementation implements Serializable { + private final Object id; private final Type type; private final String entityOrRoleName; private final String tenantId; @@ -37,13 +43,13 @@ public class CacheKey implements Serializable { * @param tenantId The tenant identifier associated this data. * @param factory The session factory for which we are caching */ - public CacheKey( - final Serializable id, + OldCacheKeyImplementation( + final Object id, final Type type, final String entityOrRoleName, final String tenantId, final SessionFactoryImplementor factory) { - this.key = id; + this.id = id; this.type = type; this.entityOrRoleName = entityOrRoleName; this.tenantId = tenantId; @@ -51,21 +57,13 @@ public CacheKey( } private int calculateHashCode(Type type, SessionFactoryImplementor factory) { - int result = type.getHashCode( key, factory ); + int result = type.getHashCode(id, factory ); result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0); return result; } - public Serializable getKey() { - return key; - } - - public String getEntityOrRoleName() { - return entityOrRoleName; - } - - public String getTenantId() { - return tenantId; + public Object getId() { + return id; } @Override @@ -76,13 +74,13 @@ public boolean equals(Object other) { if ( this == other ) { return true; } - if ( hashCode != other.hashCode() || !( other instanceof CacheKey ) ) { + if ( hashCode != other.hashCode() || !( other instanceof OldCacheKeyImplementation ) ) { //hashCode is part of this check since it is pre-calculated and hash must match for equals to be true return false; } - final CacheKey that = (CacheKey) other; + final OldCacheKeyImplementation that = (OldCacheKeyImplementation) other; return EqualsHelper.equals( entityOrRoleName, that.entityOrRoleName ) - && type.isEqual( key, that.key ) + && type.isEqual(id, that.id) && EqualsHelper.equals( tenantId, that.tenantId ); } @@ -94,6 +92,6 @@ public int hashCode() { @Override public String toString() { // Used to be required for OSCache - return entityOrRoleName + '#' + key.toString(); + return entityOrRoleName + '#' + id.toString(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java similarity index 89% rename from hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java rename to hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java index eb1e2a70665d..3cda42099318 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java @@ -4,7 +4,7 @@ * 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; +package org.hibernate.cache.internal; import java.io.IOException; import java.io.ObjectInputStream; @@ -22,10 +22,16 @@ /** * Defines a key for caching natural identifier resolutions into the second level cache. * + * This was named org.hibernate.cache.spi.NaturalIdCacheKey in Hibernate until version 5. + * Temporarily maintained as a reference while all components catch up with the refactoring to the caching interfaces. + * * @author Eric Dalquist * @author Steve Ebersole + * + * @deprecated Cache implementation should provide optimized key. */ -public class NaturalIdCacheKey implements Serializable { +@Deprecated +public class OldNaturalIdCacheKey implements Serializable { private final Serializable[] naturalIdValues; private final String entityName; private final String tenantId; @@ -35,13 +41,12 @@ public class NaturalIdCacheKey implements Serializable { /** * Construct a new key for a caching natural identifier resolutions into the second level cache. - * Note that an entity name should always be the root entity name, not a subclass entity name. * * @param naturalIdValues The naturalIdValues associated with the cached data * @param persister The persister for the entity * @param session The originating session */ - public NaturalIdCacheKey( + public OldNaturalIdCacheKey( final Object[] naturalIdValues, final EntityPersister persister, final SessionImplementor session) { @@ -137,12 +142,12 @@ public boolean equals(Object o) { return true; } - if ( hashCode != o.hashCode() || !( o instanceof NaturalIdCacheKey ) ) { + if ( hashCode != o.hashCode() || !( o instanceof OldNaturalIdCacheKey ) ) { //hashCode is part of this check since it is pre-calculated and hash must match for equals to be true return false; } - final NaturalIdCacheKey other = (NaturalIdCacheKey) o; + final OldNaturalIdCacheKey other = (OldNaturalIdCacheKey) o; return EqualsHelper.equals( entityName, other.entityName ) && EqualsHelper.equals( tenantId, other.tenantId ) && Arrays.deepEquals( this.naturalIdValues, other.naturalIdValues ); diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java index 7bf21b364c82..621dc3c992e0 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java @@ -7,6 +7,8 @@ package org.hibernate.cache.spi.access; import org.hibernate.cache.spi.CollectionRegion; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * Contract for managing transactional and concurrent access to cached collection @@ -23,6 +25,25 @@ */ public interface CollectionRegionAccessStrategy extends RegionAccessStrategy { + /** + * To create instances of CollectionCacheKey for this region, Hibernate will invoke this method + * exclusively so that generated implementations can generate optimised keys. + * @param id the primary identifier of the Collection + * @param persister the persister for the type for which a key is being generated + * @param factory a reference to the current SessionFactory + * @param tenantIdentifier the tenant id, or null if multi-tenancy is not being used. + * @return a key which can be used to identify this collection on this same region + */ + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier); + + /** + * Performs reverse operation to {@link #generateCacheKey(Object, CollectionPersister, SessionFactoryImplementor, String)} + * + * @param cacheKey key previously returned from {@link #generateCacheKey(Object, CollectionPersister, SessionFactoryImplementor, String)} + * @return original key passed to {@link #generateCacheKey(Object, CollectionPersister, SessionFactoryImplementor, String)} + */ + public Object getCacheKeyId(Object cacheKey); + /** * Get the wrapped collection cache region * diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java index b63c85fa33c7..32c5382b94b2 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java @@ -8,6 +8,8 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.EntityRegion; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Contract for managing transactional and concurrent access to cached entity @@ -25,7 +27,26 @@ * @author Gavin King * @author Steve Ebersole */ -public interface EntityRegionAccessStrategy extends RegionAccessStrategy{ +public interface EntityRegionAccessStrategy extends RegionAccessStrategy { + + /** + * To create instances of EntityCacheKey for this region, Hibernate will invoke this method + * exclusively so that generated implementations can generate optimised keys. + * @param id the primary identifier of the entity + * @param persister the persister for the type for which a key is being generated + * @param factory a reference to the current SessionFactory + * @param tenantIdentifier the tenant id, or null if multi-tenancy is not being used. + * @return a key which can be used to identify this entity on this same region + */ + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier); + + /** + * Performs reverse operation to {@link #generateCacheKey(Object, EntityPersister, SessionFactoryImplementor, String)} + * + * @param cacheKey key previously returned from {@link #generateCacheKey(Object, EntityPersister, SessionFactoryImplementor, String)} + * @return original id passed to {@link #generateCacheKey(Object, EntityPersister, SessionFactoryImplementor, String)} + */ + public Object getCacheKeyId(Object cacheKey); /** * Get the wrapped entity cache region @@ -43,7 +64,7 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{ * @param value The item * @param version The item's version value * @return Were the contents of the cache actual changed by this operation? - * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} + * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} */ public boolean insert(Object key, Object value, Object version) throws CacheException; @@ -56,7 +77,7 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{ * @param value The item * @param version The item's version value * @return Were the contents of the cache actual changed by this operation? - * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} + * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} */ public boolean afterInsert(Object key, Object value, Object version) throws CacheException; @@ -70,7 +91,7 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{ * @param currentVersion The item's current version value * @param previousVersion The item's previous version value * @return Were the contents of the cache actual changed by this operation? - * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} + * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} */ public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException; @@ -85,7 +106,7 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{ * @param previousVersion The item's previous version value * @param lock The lock previously obtained from {@link #lockItem} * @return Were the contents of the cache actual changed by this operation? - * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} + * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} */ public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java index 83e4c8871a7c..bbf60eb8c9a3 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java @@ -8,6 +8,8 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.NaturalIdRegion; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Contract for managing transactional and concurrent access to cached naturalId @@ -36,6 +38,24 @@ */ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy { + /** + * To create instances of NaturalIdCacheKey for this region, Hibernate will invoke this method + * exclusively so that generated implementations can generate optimised keys. + * @param naturalIdValues the sequence of values which unequivocally identifies a cached element on this region + * @param persister the persister of the element being cached + * @param session + * @return a key which can be used to identify this an element unequivocally on this same region + */ + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session); + + /** + * Performs reverse operation to {@link #generateCacheKey(Object[], EntityPersister, SessionImplementor)}, returning + * the original naturalIdValues. + * @param cacheKey key returned from {@link #generateCacheKey(Object[], EntityPersister, SessionImplementor)} + * @return the sequence of values which unequivocally identifies a cached element on this region + */ + public Object[] getNaturalIdValues(Object cacheKey); + /** * Get the wrapped naturalId cache region * @@ -51,7 +71,7 @@ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy { * @param key The item key * @param value The item * @return Were the contents of the cache actual changed by this operation? - * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} + * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} */ public boolean insert(Object key, Object value) throws CacheException; @@ -63,7 +83,7 @@ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy { * @param key The item key * @param value The item * @return Were the contents of the cache actual changed by this operation? - * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} + * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} */ public boolean afterInsert(Object key, Object value) throws CacheException; @@ -75,7 +95,7 @@ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy { * @param key The item key * @param value The item * @return Were the contents of the cache actual changed by this operation? - * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} + * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region} */ public boolean update(Object key, Object value) throws CacheException; diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java index a06b22c4be6d..42e4b8d71095 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java @@ -6,6 +6,7 @@ */ package org.hibernate.cache.spi.access; + import org.hibernate.cache.CacheException; /** @@ -14,6 +15,7 @@ * @author Gail Badner */ public interface RegionAccessStrategy { + /** * Attempt to retrieve an object from the cache. Mainly used in attempting * to resolve entities/collections from the second level cache. diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java index 884b4736fe2c..6eb0ff52dad7 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java @@ -8,45 +8,33 @@ import java.io.Serializable; -import org.hibernate.cache.spi.CacheKey; -import org.hibernate.cache.spi.NaturalIdCacheKey; -import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.RegionAccessStrategy; +import org.hibernate.engine.spi.SessionEventListenerManager; import org.hibernate.engine.spi.SessionImplementor; /** * @author Steve Ebersole + * @author Sanne Grinovero */ public final class CacheHelper { + private CacheHelper() { } public static Serializable fromSharedCache( - SessionImplementor session, - NaturalIdCacheKey cacheKey, - NaturalIdRegionAccessStrategy cacheAccessStrategy) { - return fromSharedCache( session, (Object) cacheKey, cacheAccessStrategy ); - } - - private static Serializable fromSharedCache( SessionImplementor session, Object cacheKey, RegionAccessStrategy cacheAccessStrategy) { + final SessionEventListenerManager eventListenerManager = session.getEventListenerManager(); Serializable cachedValue = null; + eventListenerManager.cacheGetStart(); try { - session.getEventListenerManager().cacheGetStart(); cachedValue = (Serializable) cacheAccessStrategy.get( cacheKey, session.getTimestamp() ); } finally { - session.getEventListenerManager().cacheGetEnd( cachedValue != null ); + eventListenerManager.cacheGetEnd( cachedValue != null ); } return cachedValue; } - public static Serializable fromSharedCache( - SessionImplementor session, - CacheKey cacheKey, - RegionAccessStrategy cacheAccessStrategy) { - return fromSharedCache( session, (Object) cacheKey, cacheAccessStrategy ); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java index f3a2be5ae78d..0ef204f9c841 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java @@ -15,7 +15,6 @@ import java.util.concurrent.ConcurrentHashMap; import org.hibernate.AssertionFailure; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -110,12 +109,12 @@ public Object[] removeNaturalIdCrossReference(EntityPersister persister, Seriali if ( persister.hasNaturalIdCache() ) { final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister .getNaturalIdCacheAccessStrategy(); - final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session() ); + final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() ); naturalIdCacheAccessStrategy.evict( naturalIdCacheKey ); if ( sessionCachedNaturalIdValues != null && !Arrays.equals( sessionCachedNaturalIdValues, naturalIdValues ) ) { - final NaturalIdCacheKey sessionNaturalIdCacheKey = new NaturalIdCacheKey( sessionCachedNaturalIdValues, persister, session() ); + final Object sessionNaturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( sessionCachedNaturalIdValues, persister, session() ); naturalIdCacheAccessStrategy.evict( sessionNaturalIdCacheKey ); } } @@ -239,9 +238,9 @@ public Serializable findCachedNaturalIdResolution(EntityPersister persister, Obj } // Try resolution from second-level cache - final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session() ); - final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy(); + final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() ); + pk = CacheHelper.fromSharedCache( session(), naturalIdCacheKey, naturalIdCacheAccessStrategy ); // Found in second-level cache, store in session cache diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java index ad511753d424..becb76f8b4a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java @@ -31,7 +31,6 @@ import org.hibernate.PersistentObjectException; import org.hibernate.TransientObjectException; import org.hibernate.action.spi.AfterTransactionCompletionProcess; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.collection.spi.PersistentCollection; @@ -1738,7 +1737,7 @@ private void managedSharedCacheEntries( Object[] previousNaturalIdValues, CachedNaturalIdValueSource source) { final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy(); - final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session ); + final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session ); final SessionFactoryImplementor factory = session.getFactory(); @@ -1793,7 +1792,7 @@ public void doAfterTransactionCompletion(boolean success, SessionImplementor ses break; } case UPDATE: { - final NaturalIdCacheKey previousCacheKey = new NaturalIdCacheKey( previousNaturalIdValues, persister, session ); + final Object previousCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( previousNaturalIdValues, persister, session ); if ( naturalIdCacheKey.equals( previousCacheKey ) ) { // prevent identical re-caching, solves HHH-7309 return; @@ -1877,7 +1876,7 @@ public void removeSharedNaturalIdCrossReference(EntityPersister persister, Seria persister = locateProperPersister( persister ); final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy(); - final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session ); + final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session ); naturalIdCacheAccessStrategy.evict( naturalIdCacheKey ); // if ( sessionCachedNaturalIdValues != null diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java index 546e55ed423d..432610c58cbc 100755 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java @@ -13,11 +13,12 @@ import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.PersistenceContext; +import org.hibernate.engine.spi.SessionEventListenerManager; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.Status; @@ -182,7 +183,8 @@ private static void doInitializeEntity( final Object version = Versioning.getVersion( hydratedState, persister ); final CacheEntry entry = persister.buildCacheEntry( entity, hydratedState, version, session ); - final CacheKey cacheKey = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() ); + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object cacheKey = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() ); // explicit handling of caching for rows just inserted and then somehow forced to be read // from the database *within the same transaction*. usually this is done by @@ -191,7 +193,7 @@ private static void doInitializeEntity( // // we need to be careful not to clobber the lock here in the cache so that it can be rolled back if need be if ( session.getPersistenceContext().wasInsertedDuringTransaction( persister, id ) ) { - persister.getCacheAccessStrategy().update( + cache.update( cacheKey, persister.getCacheEntryStructure().structure( entry ), version, @@ -199,9 +201,10 @@ private static void doInitializeEntity( ); } else { + final SessionEventListenerManager eventListenerManager = session.getEventListenerManager(); try { - session.getEventListenerManager().cachePutStart(); - final boolean put = persister.getCacheAccessStrategy().putFromLoad( + eventListenerManager.cachePutStart(); + final boolean put = cache.putFromLoad( cacheKey, persister.getCacheEntryStructure().structure( entry ), session.getTimestamp(), @@ -210,11 +213,11 @@ private static void doInitializeEntity( ); if ( put && factory.getStatistics().isStatisticsEnabled() ) { - factory.getStatisticsImplementor().secondLevelCachePut( persister.getCacheAccessStrategy().getRegion().getName() ); + factory.getStatisticsImplementor().secondLevelCachePut( cache.getRegion().getName() ); } } finally { - session.getEventListenerManager().cachePutEnd(); + eventListenerManager.cachePutEnd(); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java index 0e4399f82cf6..af8624032a4f 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java @@ -17,7 +17,7 @@ import org.hibernate.CacheMode; import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.entry.CollectionCacheEntry; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.CollectionEntry; @@ -332,7 +332,13 @@ private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersiste } final CollectionCacheEntry entry = new CollectionCacheEntry( lce.getCollection(), persister ); - final CacheKey cacheKey = session.generateCacheKey( lce.getKey(), persister.getKeyType(), persister.getRole() ); + final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object cacheKey = cache.generateCacheKey( + lce.getKey(), + persister, + session.getFactory(), + session.getTenantIdentifier() + ); boolean isPutFromLoad = true; if ( persister.getElementType().isAssociationType() ) { @@ -349,7 +355,7 @@ private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersiste if (isPutFromLoad) { try { session.getEventListenerManager().cachePutStart(); - final boolean put = persister.getCacheAccessStrategy().putFromLoad( + final boolean put = cache.putFromLoad( cacheKey, persister.getCacheEntryStructure().structure( entry ), session.getTimestamp(), diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/BatchFetchQueue.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/BatchFetchQueue.java index 0a721b4c301b..b28669d43be5 100755 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/BatchFetchQueue.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/BatchFetchQueue.java @@ -14,7 +14,8 @@ import java.util.Map.Entry; import org.hibernate.EntityMode; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.internal.CacheHelper; import org.hibernate.internal.CoreLogging; @@ -201,13 +202,16 @@ public Serializable[] getEntityBatch( } private boolean isCached(EntityKey entityKey, EntityPersister persister) { + final SessionImplementor session = context.getSession(); if ( context.getSession().getCacheMode().isGetEnabled() && persister.hasCache() ) { - final CacheKey key = context.getSession().generateCacheKey( + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object key = cache.generateCacheKey( entityKey.getIdentifier(), - persister.getIdentifierType(), - persister.getRootEntityName() + persister, + session.getFactory(), + session.getTenantIdentifier() ); - return CacheHelper.fromSharedCache( context.getSession(), key, persister.getCacheAccessStrategy() ) != null; + return CacheHelper.fromSharedCache( session, key, cache ) != null; } return false; } @@ -314,14 +318,18 @@ else if ( !isCached( ce.getLoadedKey(), collectionPersister ) ) { } private boolean isCached(Serializable collectionKey, CollectionPersister persister) { - if ( context.getSession().getCacheMode().isGetEnabled() && persister.hasCache() ) { - CacheKey cacheKey = context.getSession().generateCacheKey( + SessionImplementor session = context.getSession(); + if ( session.getCacheMode().isGetEnabled() && persister.hasCache() ) { + CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + Object cacheKey = cache.generateCacheKey( collectionKey, - persister.getKeyType(), - persister.getRole() + persister, + session.getFactory(), + session.getTenantIdentifier() ); - return CacheHelper.fromSharedCache( context.getSession(), cacheKey, persister.getCacheAccessStrategy() ) != null; + return CacheHelper.fromSharedCache( session, cacheKey, cache ) != null; } return false; } + } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java index 68d2e2cb0b7d..5bbe3c475867 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java @@ -35,7 +35,6 @@ import org.hibernate.Transaction; import org.hibernate.TypeHelper; import org.hibernate.UnknownProfileException; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.spi.JdbcCoordinator; @@ -47,7 +46,6 @@ import org.hibernate.procedure.ProcedureCall; import org.hibernate.resource.transaction.TransactionCoordinator; import org.hibernate.stat.SessionStatistics; -import org.hibernate.type.Type; /** * This class is meant to be extended. @@ -97,11 +95,6 @@ public EntityKey generateEntityKey(Serializable id, EntityPersister persister) { return sessionImplementor.generateEntityKey( id, persister ); } - @Override - public CacheKey generateCacheKey(Serializable id, Type type, String entityOrRoleName) { - return sessionImplementor.generateCacheKey( id, type, entityOrRoleName ); - } - @Override public Interceptor getInterceptor() { return sessionImplementor.getInterceptor(); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java index 6dc65a61a2ce..86cd592ba983 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java @@ -6,29 +6,19 @@ */ package org.hibernate.engine.spi; +import javax.naming.NamingException; +import javax.naming.Reference; import java.sql.Connection; import java.util.Map; import java.util.Properties; import java.util.Set; -import javax.naming.NamingException; -import javax.naming.Reference; -import org.hibernate.Cache; -import org.hibernate.CustomEntityDirtinessStrategy; -import org.hibernate.EntityNameResolver; -import org.hibernate.HibernateException; -import org.hibernate.Interceptor; -import org.hibernate.MappingException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.SessionFactoryObserver; -import org.hibernate.StatelessSession; -import org.hibernate.StatelessSessionBuilder; -import org.hibernate.TypeHelper; +import org.hibernate.*; import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.UpdateTimestampsCache; +import org.hibernate.cache.spi.access.RegionAccessStrategy; import org.hibernate.cfg.Settings; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.dialect.Dialect; @@ -292,11 +282,21 @@ public Region getSecondLevelCacheRegion(String regionName) { return delegate.getSecondLevelCacheRegion( regionName ); } + @Override + public RegionAccessStrategy getSecondLevelCacheRegionAccessStrategy(String regionName) { + return delegate.getSecondLevelCacheRegionAccessStrategy(regionName); + } + @Override public Region getNaturalIdCacheRegion(String regionName) { return delegate.getNaturalIdCacheRegion( regionName ); } + @Override + public RegionAccessStrategy getNaturalIdCacheRegionAccessStrategy(String regionName) { + return delegate.getNaturalIdCacheRegionAccessStrategy(regionName); + } + @Override public Map getAllSecondLevelCacheRegions() { return delegate.getAllSecondLevelCacheRegions(); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java index a889d82dc41b..6bb7ae38fe33 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java @@ -22,6 +22,7 @@ import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.UpdateTimestampsCache; +import org.hibernate.cache.spi.access.RegionAccessStrategy; import org.hibernate.cfg.Settings; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.dialect.Dialect; @@ -190,6 +191,13 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { * @return The region */ Region getSecondLevelCacheRegion(String regionName); + + /** + * Get access strategy to second-level cache region + * @param regionName + * @return + */ + RegionAccessStrategy getSecondLevelCacheRegionAccessStrategy(String regionName); /** * Get a named naturalId cache region @@ -199,6 +207,13 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { */ Region getNaturalIdCacheRegion(String regionName); + /** + * Get access strategy to naturalId cache region + * @param regionName + * @return + */ + RegionAccessStrategy getNaturalIdCacheRegionAccessStrategy(String regionName); + /** * Get a map of all the second level cache regions currently maintained in * this session factory. The map is structured with the region name as the diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java index fe1c164f7151..9ed6dfa3b9a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java @@ -20,7 +20,6 @@ import org.hibernate.SQLQuery; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; @@ -64,17 +63,6 @@ public interface SessionImplementor extends Serializable, LobCreationContext { */ EntityKey generateEntityKey(Serializable id, EntityPersister persister); - /** - * Hide the changing requirements of cache key creation. - * - * @param id The entity identifier or collection key. - * @param type The type - * @param entityOrRoleName The entity name or collection role. - * - * @return The cache key - */ - CacheKey generateCacheKey(Serializable id, final Type type, final String entityOrRoleName); - /** * Retrieves the interceptor currently in use by this event source. * diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java index 1d8a5851e3d1..66169048d299 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java @@ -9,7 +9,7 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.ObjectDeletedException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.Status; @@ -17,7 +17,6 @@ import org.hibernate.internal.CoreLogging; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; - import org.jboss.logging.Logger; /** @@ -62,18 +61,16 @@ protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOpt ); } - final SoftLock lock; - final CacheKey ck; - if ( persister.hasCache() ) { - ck = source.generateCacheKey( entry.getId(), persister.getIdentifierType(), persister.getRootEntityName() ); - lock = persister.getCacheAccessStrategy().lockItem( ck, entry.getVersion() ); - } - else { - ck = null; - lock = null; - } - + final boolean cachingEnabled = persister.hasCache(); + SoftLock lock = null; + Object ck = null; try { + if ( cachingEnabled ) { + EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + ck = cache.generateCacheKey( entry.getId(), persister, source.getFactory(), source.getTenantIdentifier() ); + lock = cache.lockItem( ck, entry.getVersion() ); + } + if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE ) { // todo : should we check the current isolation mode explicitly? Object nextVersion = persister.forceVersionIncrement( @@ -89,7 +86,7 @@ protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOpt finally { // the database now holds a lock + the object is flushed from the cache, // so release the soft lock - if ( persister.hasCache() ) { + if ( cachingEnabled ) { persister.getCacheAccessStrategy().unlockItem( ck, lock ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java index 38cc1b518b5e..2118ecd20bc6 100755 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java @@ -9,7 +9,7 @@ import java.io.Serializable; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.entry.CollectionCacheEntry; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.internal.CacheHelper; @@ -116,17 +116,18 @@ private boolean initializeCollectionFromCache( } final SessionFactoryImplementor factory = source.getFactory(); - final CacheKey ck = source.generateCacheKey( id, persister.getKeyType(), persister.getRole() ); + final CollectionRegionAccessStrategy cacheAccessStrategy = persister.getCacheAccessStrategy(); + final Object ck = cacheAccessStrategy.generateCacheKey( id, persister, factory, source.getTenantIdentifier() ); final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() ); if ( factory.getStatistics().isStatisticsEnabled() ) { if ( ce == null ) { factory.getStatisticsImplementor() - .secondLevelCacheMiss( persister.getCacheAccessStrategy().getRegion().getName() ); + .secondLevelCacheMiss( cacheAccessStrategy.getRegion().getName() ); } else { factory.getStatisticsImplementor() - .secondLevelCacheHit( persister.getCacheAccessStrategy().getRegion().getName() ); + .secondLevelCacheHit( cacheAccessStrategy.getRegion().getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java index 11d4984761e9..135ea67787e0 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java @@ -14,7 +14,7 @@ import org.hibernate.PersistentObjectException; import org.hibernate.TypeMismatchException; import org.hibernate.WrongClassException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl; @@ -357,12 +357,14 @@ protected Object lockAndLoad( final LoadEventListener.LoadType options, final SessionImplementor source) { SoftLock lock = null; - final CacheKey ck; + final Object ck; + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); if ( persister.hasCache() ) { - ck = source.generateCacheKey( + ck = cache.generateCacheKey( event.getEntityId(), - persister.getIdentifierType(), - persister.getRootEntityName() + persister, + source.getFactory(), + source.getTenantIdentifier() ); lock = persister.getCacheAccessStrategy().lockItem( ck, null ); } @@ -376,7 +378,7 @@ protected Object lockAndLoad( } finally { if ( persister.hasCache() ) { - persister.getCacheAccessStrategy().unlockItem( ck, lock ); + cache.unlockItem( ck, lock ); } } @@ -572,22 +574,24 @@ protected Object loadFromSecondLevelCache( } final SessionFactoryImplementor factory = source.getFactory(); - final CacheKey ck = source.generateCacheKey( + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( event.getEntityId(), - persister.getIdentifierType(), - persister.getRootEntityName() + persister, + factory, + source.getTenantIdentifier() ); final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() ); if ( factory.getStatistics().isStatisticsEnabled() ) { if ( ce == null ) { factory.getStatisticsImplementor().secondLevelCacheMiss( - persister.getCacheAccessStrategy().getRegion().getName() + cache.getRegion().getName() ); } else { factory.getStatisticsImplementor().secondLevelCacheHit( - persister.getCacheAccessStrategy().getRegion().getName() + cache.getRegion().getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultRefreshEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultRefreshEventListener.java index fc01c483681b..6ca71fe98da9 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultRefreshEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultRefreshEventListener.java @@ -13,7 +13,7 @@ import org.hibernate.HibernateException; import org.hibernate.PersistentObjectException; import org.hibernate.UnresolvableObjectException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.engine.internal.Cascade; import org.hibernate.engine.internal.CascadePoint; import org.hibernate.engine.spi.CascadingActions; @@ -136,12 +136,14 @@ public void onRefresh(RefreshEvent event, Map refreshedAlready) { } if ( persister.hasCache() ) { - final CacheKey ck = source.generateCacheKey( + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + Object ck = cache.generateCacheKey( id, - persister.getIdentifierType(), - persister.getRootEntityName() + persister, + source.getFactory(), + source.getTenantIdentifier() ); - persister.getCacheAccessStrategy().evict( ck ); + cache.evict( ck ); } evictCachedCollections( persister, id, source.getFactory() ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java index cc330e1f5aa8..96131d991c99 100755 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java @@ -26,7 +26,6 @@ import org.hibernate.SharedSessionContract; import org.hibernate.Transaction; import org.hibernate.boot.spi.SessionFactoryOptions; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; @@ -58,7 +57,6 @@ import org.hibernate.resource.transaction.TransactionCoordinatorBuilder.TransactionCoordinatorOptions; import org.hibernate.resource.transaction.spi.TransactionStatus; import org.hibernate.service.ServiceRegistry; -import org.hibernate.type.Type; /** * Functionality common to stateless and stateful sessions @@ -336,11 +334,6 @@ public EntityKey generateEntityKey(Serializable id, EntityPersister persister) { return new EntityKey( id, persister ); } - @Override - public CacheKey generateCacheKey(Serializable id, Type type, String entityOrRoleName) { - return new CacheKey( id, type, entityOrRoleName, getTenantIdentifier(), getFactory() ); - } - private transient JdbcConnectionAccess jdbcConnectionAccess; @Override diff --git a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java index 94769b542ad9..dfac9b16a3de 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java @@ -14,11 +14,12 @@ import org.hibernate.HibernateException; import org.hibernate.boot.spi.SessionFactoryOptions; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.UpdateTimestampsCache; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.engine.spi.CacheImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.CollectionHelper; @@ -73,8 +74,14 @@ public boolean containsEntity(Class entityClass, Serializable identifier) { @Override public boolean containsEntity(String entityName, Serializable identifier) { EntityPersister p = sessionFactory.getEntityPersister( entityName ); - return p.hasCache() && - p.getCacheAccessStrategy().getRegion().contains( buildCacheKey( identifier, p ) ); + if ( p.hasCache() ) { + EntityRegionAccessStrategy cache = p.getCacheAccessStrategy(); + Object key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy + return cache.getRegion().contains( key ); + } + else { + return false; + } } @Override @@ -92,20 +99,12 @@ public void evictEntity(String entityName, Serializable identifier) { MessageHelper.infoString( p, identifier, sessionFactory ) ); } - p.getCacheAccessStrategy().evict( buildCacheKey( identifier, p ) ); + EntityRegionAccessStrategy cache = p.getCacheAccessStrategy(); + Object key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy + cache.evict( key ); } } - private CacheKey buildCacheKey(Serializable identifier, EntityPersister p) { - return new CacheKey( - identifier, - p.getIdentifierType(), - p.getRootEntityName(), - null, // have to assume non tenancy - sessionFactory - ); - } - @Override public void evictEntityRegion(Class entityClass) { evictEntityRegion( entityClass.getName() ); @@ -155,8 +154,14 @@ public void evictNaturalIdRegions() { @Override public boolean containsCollection(String role, Serializable ownerIdentifier) { CollectionPersister p = sessionFactory.getCollectionPersister( role ); - return p.hasCache() && - p.getCacheAccessStrategy().getRegion().contains( buildCacheKey( ownerIdentifier, p ) ); + if ( p.hasCache() ) { + CollectionRegionAccessStrategy cache = p.getCacheAccessStrategy(); + Object key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy + return cache.getRegion().contains( key ); + } + else { + return false; + } } @Override @@ -169,21 +174,12 @@ public void evictCollection(String role, Serializable ownerIdentifier) { MessageHelper.collectionInfoString( p, ownerIdentifier, sessionFactory ) ); } - CacheKey cacheKey = buildCacheKey( ownerIdentifier, p ); - p.getCacheAccessStrategy().evict( cacheKey ); + CollectionRegionAccessStrategy cache = p.getCacheAccessStrategy(); + Object key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy + cache.evict( key ); } } - private CacheKey buildCacheKey(Serializable ownerIdentifier, CollectionPersister p) { - return new CacheKey( - ownerIdentifier, - p.getKeyType(), - p.getRole(), - null, // have to assume non tenancy - sessionFactory - ); - } - @Override public void evictCollectionRegion(String role) { CollectionPersister p = sessionFactory.getCollectionPersister( role ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index d77fbb730fd3..267156505393 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.hibernate.cache.spi.access.RegionAccessStrategy; import org.jboss.logging.Logger; import org.hibernate.AssertionFailure; @@ -201,6 +202,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { private final transient TypeResolver typeResolver; private final transient TypeHelper typeHelper; private final transient SessionFactoryOptions sessionFactoryOptions; + private final transient Map cacheAccessStrategiesMap = new HashMap(); public SessionFactoryImpl(final MetadataImplementor metadata, SessionFactoryOptions options) { LOG.debug( "Building session factory" ); @@ -320,7 +322,6 @@ public MetadataImplementor getMetadata() { // todo : similar for CollectionPersister/CollectionMetadata this.entityPersisters = new HashMap(); - Map cacheAccessStrategiesMap = new HashMap(); Map inFlightClassMetadataMap = new HashMap(); this.entityProxyInterfaceMap = CollectionHelper.concurrentMap( metadata.getEntityBindings().size() ); for ( final PersistentClass model : metadata.getEntityBindings() ) { @@ -430,6 +431,7 @@ public MetadataImplementor getMetadata() { roles.add( persister.getRole() ); } } + this.collectionMetadata = Collections.unmodifiableMap( tmpCollectionMetadata ); for ( Map.Entry> entityToCollectionRoleMapEntry : inFlightEntityToCollectionRoleMap.entrySet() ) { @@ -1130,10 +1132,20 @@ public Region getSecondLevelCacheRegion(String regionName) { return cacheAccess.getSecondLevelCacheRegion( regionName ); } + @Override + public RegionAccessStrategy getSecondLevelCacheRegionAccessStrategy(String regionName) { + return cacheAccessStrategiesMap.get(regionName); + } + public Region getNaturalIdCacheRegion(String regionName) { return cacheAccess.getNaturalIdCacheRegion( regionName ); } + @Override + public RegionAccessStrategy getNaturalIdCacheRegionAccessStrategy(String regionName) { + return cacheAccessStrategiesMap.get(regionName); + } + @SuppressWarnings( {"unchecked"}) public Map getAllSecondLevelCacheRegions() { return cacheAccess.getAllSecondLevelCacheRegions(); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java index 404b572d1923..9c2c42507284 100755 --- a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java @@ -28,7 +28,7 @@ import org.hibernate.StatelessSession; import org.hibernate.Transaction; import org.hibernate.UnresolvableObjectException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.internal.SessionEventListenerManagerImpl; import org.hibernate.engine.internal.StatefulPersistenceContext; @@ -270,8 +270,9 @@ public void refresh(String entityName, Object entity, LockMode lockMode) { // } if ( persister.hasCache() ) { - final CacheKey ck = generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() ); - persister.getCacheAccessStrategy().evict( ck ); + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( id, persister, getFactory(), getTenantIdentifier() ); + cache.evict( ck ); } String previousFetchProfile = this.getLoadQueryInfluencers().getInternalFetchProfile(); Object result = null; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java index 84c01c97fff1..51bc9b9a2b01 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -35,6 +35,7 @@ import org.hibernate.cache.spi.FilterKey; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.QueryKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl; import org.hibernate.collection.spi.PersistentCollection; @@ -1620,15 +1621,14 @@ private Object instanceNotYetLoaded( // see if the entity defines reference caching, and if so use the cached reference (if one). if ( session.getCacheMode().isGetEnabled() && persister.canUseReferenceCacheEntries() ) { - final Object cachedEntry = CacheHelper.fromSharedCache( - session, - session.generateCacheKey( - key.getIdentifier(), - persister.getEntityMetamodel().getEntityType(), - key.getEntityName() - ), - persister.getCacheAccessStrategy() - ); + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( + key.getIdentifier(), + persister, + session.getFactory(), + session.getTenantIdentifier() + ); + final Object cachedEntry = CacheHelper.fromSharedCache( session, ck, cache ); if ( cachedEntry != null ) { CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( cachedEntry, factory ); return ( (ReferenceCacheEntryImpl) entry ).getReference(); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 34de9320e3d3..3d4ea3adc7fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -36,7 +36,6 @@ import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor; import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer; import org.hibernate.bytecode.spi.EntityInstrumentationMetadata; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; @@ -906,8 +905,9 @@ public Object initializeLazyProperty(String fieldName, Object entity, SessionImp } if ( session.getCacheMode().isGetEnabled() && hasCache() ) { - final CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getRootEntityName() ); - final Object ce = CacheHelper.fromSharedCache( session, cacheKey, getCacheAccessStrategy() ); + final EntityRegionAccessStrategy cache = getCacheAccessStrategy(); + final Object cacheKey = cache.generateCacheKey(id, this, session.getFactory(), session.getTenantIdentifier() ); + final Object ce = CacheHelper.fromSharedCache( session, cacheKey, cache ); if ( ce != null ) { final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure( ce, factory ); if ( !cacheEntry.areLazyPropertiesUnfetched() ) { @@ -4269,7 +4269,8 @@ public Boolean isTransient(Object entity, SessionImplementor session) throws Hib // check to see if it is in the second-level cache if ( session.getCacheMode().isGetEnabled() && hasCache() ) { - final CacheKey ck = session.generateCacheKey( id, getIdentifierType(), getRootEntityName() ); + final EntityRegionAccessStrategy cache = getCacheAccessStrategy(); + final Object ck = cache.generateCacheKey( id, this, session.getFactory(), session.getTenantIdentifier() ); final Object ce = CacheHelper.fromSharedCache( session, ck, getCacheAccessStrategy() ); if ( ce != null ) { return Boolean.FALSE; diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java index db14beb0c18d..7eedbe4676f5 100644 --- a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java @@ -13,8 +13,8 @@ import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.Region; +import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.stat.NaturalIdCacheStatistics; /** @@ -25,6 +25,7 @@ public class ConcurrentNaturalIdCacheStatisticsImpl extends CategorizedStatistics implements NaturalIdCacheStatistics { private static final long serialVersionUID = 1L; private final transient Region region; + private final transient NaturalIdRegionAccessStrategy accessStrategy; private final AtomicLong hitCount = new AtomicLong(); private final AtomicLong missCount = new AtomicLong(); private final AtomicLong putCount = new AtomicLong(); @@ -35,15 +36,17 @@ public class ConcurrentNaturalIdCacheStatisticsImpl extends CategorizedStatistic private final Lock readLock; private final Lock writeLock; + { final ReadWriteLock lock = new ReentrantReadWriteLock(); this.readLock = lock.readLock(); this.writeLock = lock.writeLock(); } - ConcurrentNaturalIdCacheStatisticsImpl(Region region) { + ConcurrentNaturalIdCacheStatisticsImpl(Region region, NaturalIdRegionAccessStrategy accessStrategy) { super( region.getName() ); this.region = region; + this.accessStrategy = accessStrategy; } @Override @@ -126,8 +129,8 @@ public long getSizeInMemory() { public Map getEntries() { final Map map = new HashMap(); for ( Object o : this.region.toMap().entrySet() ) { - final Map.Entry me = (Map.Entry) o; - map.put( ( (NaturalIdCacheKey) me.getKey() ).getNaturalIdValues(), me.getValue() ); + Map.Entry me = (Map.Entry) o; + map.put( accessStrategy.getNaturalIdValues(me.getKey()), me.getValue() ); } return map; } diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentSecondLevelCacheStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentSecondLevelCacheStatisticsImpl.java index d7292d231f2a..e617f17282e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentSecondLevelCacheStatisticsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentSecondLevelCacheStatisticsImpl.java @@ -7,12 +7,12 @@ package org.hibernate.stat.internal; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.Region; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.stat.SecondLevelCacheStatistics; /** @@ -22,13 +22,19 @@ */ public class ConcurrentSecondLevelCacheStatisticsImpl extends CategorizedStatistics implements SecondLevelCacheStatistics { private final transient Region region; + private final transient EntityRegionAccessStrategy entityRegionAccessStrategy; + private final transient CollectionRegionAccessStrategy collectionRegionAccessStrategy; private AtomicLong hitCount = new AtomicLong(); private AtomicLong missCount = new AtomicLong(); private AtomicLong putCount = new AtomicLong(); - ConcurrentSecondLevelCacheStatisticsImpl(Region region) { + ConcurrentSecondLevelCacheStatisticsImpl(Region region, + EntityRegionAccessStrategy entityRegionAccessStrategy, + CollectionRegionAccessStrategy collectionRegionAccessStrategy) { super( region.getName() ); this.region = region; + this.entityRegionAccessStrategy = entityRegionAccessStrategy; + this.collectionRegionAccessStrategy = collectionRegionAccessStrategy; } public long getHitCount() { @@ -57,10 +63,19 @@ public long getSizeInMemory() { public Map getEntries() { Map map = new HashMap(); - Iterator iter = region.toMap().entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry me = (Map.Entry) iter.next(); - map.put(((CacheKey) me.getKey()).getKey(), me.getValue()); + for (Object o : region.toMap().entrySet()) { + Map.Entry me = (Map.Entry) o; + Object id; + if (entityRegionAccessStrategy != null) { + id = entityRegionAccessStrategy.getCacheKeyId(me.getKey()); + } + else if (collectionRegionAccessStrategy != null) { + id = collectionRegionAccessStrategy.getCacheKeyId(me.getKey()); + } + else { + id = me.getKey(); + } + map.put(id, me.getValue()); } return map; } diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java index b9b6e87deefd..16b5478fb6f5 100644 --- a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java @@ -11,6 +11,10 @@ import java.util.concurrent.atomic.AtomicLong; import org.hibernate.cache.spi.Region; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; +import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; +import org.hibernate.cache.spi.access.RegionAccessStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.collections.ArrayHelper; @@ -299,7 +303,10 @@ public NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName) { if ( region == null ) { return null; } - nics = new ConcurrentNaturalIdCacheStatisticsImpl( region ); + NaturalIdRegionAccessStrategy accessStrategy + = (NaturalIdRegionAccessStrategy) sessionFactory.getNaturalIdCacheRegionAccessStrategy(regionName); + + nics = new ConcurrentNaturalIdCacheStatisticsImpl( region, accessStrategy ); ConcurrentNaturalIdCacheStatisticsImpl previous; if ( ( previous = (ConcurrentNaturalIdCacheStatisticsImpl) naturalIdCacheStatistics.putIfAbsent( regionName, nics @@ -328,7 +335,16 @@ public SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionNam if ( region == null ) { return null; } - slcs = new ConcurrentSecondLevelCacheStatisticsImpl( region ); + RegionAccessStrategy accessStrategy = sessionFactory.getSecondLevelCacheRegionAccessStrategy(regionName); + + EntityRegionAccessStrategy entityRegionAccessStrategy + = accessStrategy instanceof EntityRegionAccessStrategy ? + (EntityRegionAccessStrategy) accessStrategy : null; + CollectionRegionAccessStrategy collectionRegionAccessStrategy + = accessStrategy instanceof CollectionRegionAccessStrategy ? + (CollectionRegionAccessStrategy) accessStrategy : null; + + slcs = new ConcurrentSecondLevelCacheStatisticsImpl( region, entityRegionAccessStrategy, collectionRegionAccessStrategy ); ConcurrentSecondLevelCacheStatisticsImpl previous; if ( ( previous = (ConcurrentSecondLevelCacheStatisticsImpl) secondLevelCacheStatistics.putIfAbsent( regionName, slcs 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 cd9e92612561..9143c57f202e 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 @@ -6,18 +6,13 @@ */ package org.hibernate.cache.spi; -import static junit.framework.Assert.assertEquals; -import static org.junit.Assert.assertArrayEquals; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.internal.OldNaturalIdCacheKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.entity.EntityPersister; @@ -26,6 +21,13 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertArrayEquals; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + public class NaturalIdCacheKeyTest { @Test public void testSerializationRoundTrip() throws Exception { @@ -58,15 +60,15 @@ public Object answer(InvocationOnMock invocation) throws Throwable { return invocation.getArguments()[0]; } }); - - final NaturalIdCacheKey key = new NaturalIdCacheKey(new Object[] {"a", "b", "c"}, entityPersister, sessionImplementor); + + 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); final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); - final NaturalIdCacheKey keyClone = (NaturalIdCacheKey)ois.readObject(); + final OldNaturalIdCacheKey keyClone = (OldNaturalIdCacheKey) ois.readObject(); assertEquals(key, keyClone); assertEquals(key.hashCode(), keyClone.hashCode()); diff --git a/hibernate-core/src/test/java/org/hibernate/test/filter/DynamicFilterTest.java b/hibernate-core/src/test/java/org/hibernate/test/filter/DynamicFilterTest.java index 8a3ae668bc4e..2357c7071627 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/filter/DynamicFilterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/filter/DynamicFilterTest.java @@ -20,7 +20,7 @@ import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.entry.CollectionCacheEntry; import org.hibernate.cfg.AvailableSettings; import org.hibernate.criterion.DetachedCriteria; @@ -100,12 +100,14 @@ public void testSecondLevelCachedCollectionsFiltering() { Hibernate.initialize( sp.getOrders() ); CollectionPersister persister = sessionFactory().getCollectionPersister( Salesperson.class.getName() + ".orders" ); assertTrue( "No cache for collection", persister.hasCache() ); - CacheKey cacheKey = ( (SessionImplementor) session ).generateCacheKey( + CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + Object cacheKey = cache.generateCacheKey( testData.steveId, - persister.getKeyType(), - persister.getRole() + persister, + sessionFactory(), + session.getTenantIdentifier() ); - CollectionCacheEntry cachedData = ( CollectionCacheEntry ) persister.getCacheAccessStrategy().get( cacheKey, ts ); + CollectionCacheEntry cachedData = ( CollectionCacheEntry ) cache.get( cacheKey, ts ); assertNotNull( "collection was not in cache", cachedData ); session.close(); @@ -114,14 +116,15 @@ public void testSecondLevelCachedCollectionsFiltering() { ts = ( ( SessionImplementor ) session ).getTimestamp(); session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() ); sp = ( Salesperson ) session.createQuery( "from Salesperson as s where s.id = :id" ) - .setLong( "id", testData.steveId ) - .uniqueResult(); + .setLong( "id", testData.steveId ) + .uniqueResult(); assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() ); - CacheKey cacheKey2 = ( (SessionImplementor) session ).generateCacheKey( + Object cacheKey2 = cache.generateCacheKey( testData.steveId, - persister.getKeyType(), - persister.getRole() + persister, + sessionFactory(), + session.getTenantIdentifier() ); CollectionCacheEntry cachedData2 = ( CollectionCacheEntry ) persister.getCacheAccessStrategy().get( cacheKey2, ts ); assertNotNull( "collection no longer in cache!", cachedData2 ); diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareCollectionRegionAccessStrategy.java index e22c9b5d1ebb..ffa8c52fef85 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareCollectionRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareCollectionRegionAccessStrategy.java @@ -7,11 +7,13 @@ package org.hibernate.cache.ehcache.internal.nonstop; import net.sf.ehcache.constructs.nonstop.NonStopCacheException; - import org.hibernate.cache.CacheException; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * Implementation of {@link CollectionRegionAccessStrategy} that handles {@link NonStopCacheException} using @@ -158,4 +160,13 @@ public void unlockRegion(SoftLock lock) throws CacheException { } } + @Override + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareEntityRegionAccessStrategy.java index b54154faba84..7371faaf8998 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareEntityRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareEntityRegionAccessStrategy.java @@ -7,11 +7,13 @@ package org.hibernate.cache.ehcache.internal.nonstop; import net.sf.ehcache.constructs.nonstop.NonStopCacheException; - import org.hibernate.cache.CacheException; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Implementation of {@link EntityRegionAccessStrategy} that handles {@link net.sf.ehcache.constructs.nonstop.NonStopCacheException} using @@ -203,4 +205,14 @@ public boolean update(Object key, Object value, Object currentVersion, Object pr return false; } } + + @Override + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareNaturalIdRegionAccessStrategy.java index f259b2370ab2..67d3283830b6 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareNaturalIdRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareNaturalIdRegionAccessStrategy.java @@ -7,11 +7,13 @@ package org.hibernate.cache.ehcache.internal.nonstop; import net.sf.ehcache.constructs.nonstop.NonStopCacheException; - import org.hibernate.cache.CacheException; +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; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Implementation of {@link NaturalIdRegionAccessStrategy} that handles {@link NonStopCacheException} using @@ -202,4 +204,13 @@ public void unlockRegion(SoftLock lock) throws CacheException { } } + @Override + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractReadWriteEhcacheAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractReadWriteEhcacheAccessStrategy.java index a17c67e13e05..192647e3efe2 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractReadWriteEhcacheAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractReadWriteEhcacheAccessStrategy.java @@ -16,7 +16,6 @@ import org.hibernate.cache.ehcache.EhCacheMessageLogger; import org.hibernate.cache.ehcache.internal.regions.EhcacheTransactionalDataRegion; import org.hibernate.cache.spi.access.SoftLock; - import org.jboss.logging.Logger; /** @@ -27,8 +26,7 @@ * @author Chris Dennis * @author Alex Snaps */ -abstract class AbstractReadWriteEhcacheAccessStrategy +abstract class AbstractReadWriteEhcacheAccessStrategy extends AbstractEhcacheAccessStrategy { private static final EhCacheMessageLogger LOG = Logger.getMessageLogger( diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheCollectionRegionAccessStrategy.java index 3d8170fb2712..d315942ae5e9 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheCollectionRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheCollectionRegionAccessStrategy.java @@ -9,9 +9,12 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * Ehcache specific non-strict read/write collection region access strategy @@ -79,4 +82,14 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { public void remove(Object key) throws CacheException { region().remove( key ); } + + @Override + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId( cacheKey ); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheEntityRegionAccessStrategy.java index abe9ee21b680..b6b8d95307c5 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheEntityRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheEntityRegionAccessStrategy.java @@ -9,9 +9,12 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Ehcache specific non-strict read/write entity region access strategy @@ -118,4 +121,14 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje public void remove(Object key) throws CacheException { region().remove( key ); } + + @Override + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId( cacheKey ); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy.java index a25baea452bb..dd7eff58898a 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy.java @@ -9,9 +9,12 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion; +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; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Ehcache specific non-strict read/write NaturalId region access strategy @@ -116,4 +119,14 @@ public boolean afterUpdate(Object key, Object value, SoftLock lock) throws Cache public void remove(Object key) throws CacheException { region().remove( key ); } + + @Override + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues( cacheKey ); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheCollectionRegionAccessStrategy.java index 08b1870758a1..7de3b272eddc 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheCollectionRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheCollectionRegionAccessStrategy.java @@ -9,9 +9,12 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * Ehcache specific read-only collection region access strategy @@ -68,4 +71,14 @@ public SoftLock lockItem(Object key, Object version) throws UnsupportedOperation @Override public void unlockItem(Object key, SoftLock lock) throws CacheException { } + + @Override + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheEntityRegionAccessStrategy.java index c7d0fd050644..43d16d3f7071 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheEntityRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheEntityRegionAccessStrategy.java @@ -9,9 +9,12 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Ehcache specific read-only entity region access strategy @@ -110,4 +113,14 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje throws UnsupportedOperationException { throw new UnsupportedOperationException( "Can't write to a readonly object" ); } + + @Override + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheNaturalIdRegionAccessStrategy.java index fd51e20ca433..35926666b9e9 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheNaturalIdRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheNaturalIdRegionAccessStrategy.java @@ -9,9 +9,12 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion; +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; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Ehcache specific read-only NaturalId region access strategy @@ -109,4 +112,14 @@ public boolean update(Object key, Object value) throws UnsupportedOperationExcep public boolean afterUpdate(Object key, Object value, SoftLock lock) throws UnsupportedOperationException { throw new UnsupportedOperationException( "Can't write to a readonly object" ); } + + @Override + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheCollectionRegionAccessStrategy.java index 02dd3106ed11..2402e372f325 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheCollectionRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheCollectionRegionAccessStrategy.java @@ -8,8 +8,11 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * Ehcache specific read/write collection region access strategy @@ -35,4 +38,15 @@ public ReadWriteEhcacheCollectionRegionAccessStrategy(EhcacheCollectionRegion re public CollectionRegion getRegion() { return region(); } + + + @Override + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheEntityRegionAccessStrategy.java index d887bab7d4c2..a691e2bc9a06 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheEntityRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheEntityRegionAccessStrategy.java @@ -9,9 +9,12 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Ehcache specific read/write entity region access strategy @@ -117,4 +120,14 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje region().writeUnlock( key ); } } + + @Override + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheNaturalIdRegionAccessStrategy.java index d40da2186e28..61fcb06a7dc8 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheNaturalIdRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheNaturalIdRegionAccessStrategy.java @@ -9,9 +9,12 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion; +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; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Ehcache specific read/write NaturalId region access strategy @@ -115,4 +118,14 @@ public boolean afterUpdate(Object key, Object value, SoftLock lock) throws Cache region().writeUnlock( key ); } } + + @Override + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheCollectionRegionAccessStrategy.java index dddec56ef49d..c23efe9a9419 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheCollectionRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheCollectionRegionAccessStrategy.java @@ -8,13 +8,15 @@ import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; - import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * JTA CollectionRegionAccessStrategy. @@ -100,4 +102,13 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { // no-op } + @Override + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheEntityRegionAccessStrategy.java index 82f3072cdf32..1cc4a2e504ac 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheEntityRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheEntityRegionAccessStrategy.java @@ -8,13 +8,15 @@ import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; - import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * JTA EntityRegionAccessStrategy. @@ -136,4 +138,14 @@ public boolean update( throw new CacheException( e ); } } + + @Override + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheNaturalIdRegionAccessStrategy.java index 1d5fa9a195e9..a840c2325034 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheNaturalIdRegionAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheNaturalIdRegionAccessStrategy.java @@ -8,13 +8,15 @@ import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; - import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion; +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; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * JTA NaturalIdRegionAccessStrategy. @@ -133,4 +135,13 @@ public boolean update(Object key, Object value) throws CacheException { } } + @Override + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } } 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 d174c1ad6403..a72a093c015f 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,9 +8,12 @@ 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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * Transactional collection region access for Infinispan. @@ -77,4 +80,14 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { public void unlockRegion(SoftLock lock) throws CacheException { } + @Override + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey(id, persister, factory, tenantIdentifier); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } + } 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 c9f997fe0e06..15f408144d93 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,9 +8,12 @@ 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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * Transactional entity region access for Infinispan. @@ -94,4 +97,14 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje throws CacheException { return false; } + + @Override + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/ReadOnlyAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/ReadOnlyAccess.java index a287f2b59158..adccce120b23 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/ReadOnlyAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/ReadOnlyAccess.java @@ -18,7 +18,6 @@ class ReadOnlyAccess extends TransactionalAccess { super( naturalIdRegion ); } - @Override public boolean update(Object key, Object value) throws CacheException { throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); @@ -28,4 +27,5 @@ public boolean update(Object key, Object value) throws CacheException { public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); } + } 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 b13f160398de..8817b39e3489 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,9 +8,12 @@ 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; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * @author Strong Liu @@ -103,4 +106,13 @@ public boolean afterUpdate(Object key, Object value, SoftLock lock) throws Cache return false; } + @Override + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } } 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 7ef398ba7f4a..b08b0718e86e 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 @@ -15,7 +15,6 @@ import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; import org.hibernate.cache.spi.access.AccessType; - import org.hibernate.test.cache.infinispan.util.CacheTestUtil; import org.junit.Test; 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 09ba0db2a9f5..2de5a570c9ca 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 @@ -15,15 +15,12 @@ import org.hibernate.cache.spi.GeneralDataRegion; import org.hibernate.cache.spi.QueryResultsRegion; import org.hibernate.cache.spi.Region; - import org.hibernate.test.cache.infinispan.util.CacheTestUtil; -import org.junit.Ignore; -import org.junit.Test; - import org.infinispan.AdvancedCache; import org.infinispan.transaction.tm.BatchModeTransactionManager; - import org.jboss.logging.Logger; +import org.junit.Ignore; +import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; 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 1ba12fd326a8..1d85372e9952 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 @@ -6,14 +6,15 @@ */ package org.hibernate.test.cache.infinispan.collection; +import javax.transaction.TransactionManager; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import javax.transaction.TransactionManager; +import junit.framework.AssertionFailedError; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.infinispan.access.PutFromLoadValidator; @@ -25,20 +26,17 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; 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; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import junit.framework.AssertionFailedError; - +import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.infinispan.test.CacheManagerCallable; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.transaction.tm.BatchModeTransactionManager; - import org.jboss.logging.Logger; +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; @@ -54,7 +52,6 @@ */ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends AbstractNonFunctionalTestCase { private static final Logger log = Logger.getLogger( AbstractCollectionRegionAccessStrategyTestCase.class ); - public static final String REGION_NAME = "test/com.foo.test"; public static final String KEY_BASE = "KEY"; public static final String VALUE1 = "VALUE1"; @@ -230,7 +227,7 @@ public void testPutFromLoadMinimal() throws Exception { private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ ); final CountDownLatch writeLatch1 = new CountDownLatch( 1 ); final CountDownLatch writeLatch2 = new CountDownLatch( 1 ); @@ -382,7 +379,7 @@ public void testEvictAll() throws Exception { private void evictOrRemoveTest(final boolean evict) throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ ); assertNull( "local is clean", localAccessStrategy.get( KEY, System.currentTimeMillis() ) ); assertNull( "remote is clean", remoteAccessStrategy.get( KEY, System.currentTimeMillis() ) ); @@ -413,7 +410,7 @@ public Void call() throws Exception { private void evictOrRemoveAllTest(final boolean evict) throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ ); assertEquals( 0, getValidKeyCount( localCollectionRegion.getCache().keySet() ) ); 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 81ae720d4bf0..a26b2581cde8 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 @@ -6,6 +6,8 @@ */ package org.hibernate.test.cache.infinispan.collection; +import java.util.Properties; + import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.internal.CacheDataDescriptionImpl; @@ -18,8 +20,6 @@ import org.hibernate.test.cache.infinispan.AbstractEntityCollectionRegionTestCase; import org.infinispan.AdvancedCache; -import java.util.Properties; - import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; @@ -29,6 +29,7 @@ * @author Galder ZamarreƱo */ public class CollectionRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { + private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); @Override 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 74b7a1f1c471..61503cb1ff4a 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 @@ -11,10 +11,10 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; - import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase; import org.hibernate.test.cache.infinispan.NodeEnvironment; import org.hibernate.test.cache.infinispan.util.CacheTestUtil; +import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -30,7 +30,7 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase { public static final String REGION_NAME = "test/com.foo.test"; - public static final String KEY = "KEY"; + public static final Object KEY = TestingKeyFactory.generateCollectionCacheKey( "KEY" ); public static final String VALUE1 = "VALUE1"; public static final String VALUE2 = "VALUE2"; 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 cc0153f008f3..da336ff0d976 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 @@ -11,6 +11,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import junit.framework.AssertionFailedError; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.infinispan.entity.EntityRegionImpl; @@ -20,20 +21,17 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; 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; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import junit.framework.AssertionFailedError; - +import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.infinispan.Cache; import org.infinispan.test.TestingUtil; import org.infinispan.transaction.tm.BatchModeTransactionManager; - import org.jboss.logging.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -193,7 +191,7 @@ public void testPutFromLoadMinimal() throws Exception { */ private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final CountDownLatch writeLatch1 = new CountDownLatch(1); final CountDownLatch writeLatch2 = new CountDownLatch(1); @@ -297,7 +295,7 @@ public void run() { @Test public void testInsert() throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final CountDownLatch readLatch = new CountDownLatch(1); final CountDownLatch commitLatch = new CountDownLatch(1); @@ -386,7 +384,7 @@ public void run() { @Test public void testUpdate() throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); // Set up initial state localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); @@ -502,7 +500,7 @@ public void testEvictAll() throws Exception { } private void evictOrRemoveTest(final boolean evict) throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); assertEquals(0, getValidKeyCount(localEntityRegion.getCache().keySet())); assertEquals(0, getValidKeyCount(remoteEntityRegion.getCache().keySet())); @@ -531,7 +529,7 @@ public Void call() throws Exception { } private void evictOrRemoveAllTest(final boolean evict) throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); assertEquals(0, getValidKeyCount(localEntityRegion.getCache().keySet())); assertEquals(0, getValidKeyCount(remoteEntityRegion.getCache().keySet())); assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis())); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractReadOnlyAccessTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractReadOnlyAccessTestCase.java index 7c8d7de2afe5..d3a4dbce3791 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractReadOnlyAccessTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractReadOnlyAccessTestCase.java @@ -7,10 +7,9 @@ package org.hibernate.test.cache.infinispan.entity; import org.hibernate.cache.spi.access.AccessType; - -import org.junit.Test; - +import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.infinispan.transaction.tm.BatchModeTransactionManager; +import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -42,7 +41,7 @@ public void testPutFromLoadMinimal() throws Exception { private void putFromLoadTest(boolean minimal) throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); @@ -64,8 +63,8 @@ private void putFromLoadTest(boolean minimal) throws Exception { @Test(expected = UnsupportedOperationException.class) @Override public void testUpdate() throws Exception { - localAccessStrategy.update(KEY_BASE + testCount++, - VALUE2, 2, 1); + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); + localAccessStrategy.update( KEY, VALUE2, 2, 1); } } diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractTransactionalAccessTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractTransactionalAccessTestCase.java index b390e48dc81e..fd3dce02576e 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractTransactionalAccessTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractTransactionalAccessTestCase.java @@ -10,11 +10,11 @@ import java.util.concurrent.TimeUnit; import junit.framework.AssertionFailedError; +import org.hibernate.cache.spi.access.AccessType; +import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.infinispan.transaction.tm.BatchModeTransactionManager; import org.jboss.logging.Logger; -import org.hibernate.cache.spi.access.AccessType; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -34,7 +34,7 @@ protected AccessType getAccessType() { public void testContestedPutFromLoad() throws Exception { - final String KEY = KEY_BASE + testCount++; + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); 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 f20f93320924..2752a415073a 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 @@ -6,6 +6,8 @@ */ package org.hibernate.test.cache.infinispan.entity; +import java.util.Properties; + import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.internal.CacheDataDescriptionImpl; @@ -17,8 +19,6 @@ import org.hibernate.test.cache.infinispan.AbstractEntityCollectionRegionTestCase; import org.infinispan.AdvancedCache; -import java.util.Properties; - import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; @@ -29,6 +29,7 @@ * @since 3.5 */ public class EntityRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { + private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); @Override 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 d0bc47dd2008..61fb89aa3e1b 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 @@ -7,15 +7,15 @@ package org.hibernate.test.cache.infinispan.entity; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.infinispan.InfinispanRegionFactory; +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.test.cache.infinispan.AbstractNonFunctionalTestCase; import org.hibernate.test.cache.infinispan.NodeEnvironment; import org.hibernate.test.cache.infinispan.util.CacheTestUtil; +import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -35,7 +35,7 @@ */ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase { public static final String REGION_NAME = "test/com.foo.test"; - public static final String KEY = "KEY"; + public static final Object KEY = TestingKeyFactory.generateEntityCacheKey( "KEY" ); public static final String VALUE1 = "VALUE1"; public static final String VALUE2 = "VALUE2"; 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 5ea6017f99fd..2a8ba6baf07b 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 @@ -6,11 +6,15 @@ */ package org.hibernate.test.cache.infinispan.functional.cluster; +import javax.transaction.TransactionManager; import java.util.HashSet; import java.util.Iterator; import java.util.Set; -import javax.transaction.TransactionManager; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.test.cache.infinispan.functional.Contact; +import org.hibernate.test.cache.infinispan.functional.Customer; import org.infinispan.Cache; import org.infinispan.manager.CacheContainer; import org.infinispan.notifications.Listener; @@ -21,12 +25,6 @@ import org.jboss.util.collection.ConcurrentSet; import org.junit.Test; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.cache.spi.CacheKey; -import org.hibernate.test.cache.infinispan.functional.Contact; -import org.hibernate.test.cache.infinispan.functional.Customer; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -345,9 +343,7 @@ public boolean isEmpty() { public void nodeVisited(CacheEntryVisitedEvent event) { log.debug( event.toString() ); if ( !event.isPre() ) { - CacheKey cacheKey = (CacheKey) event.getKey(); - Integer primKey = (Integer) cacheKey.getKey(); - String key = cacheKey.getEntityOrRoleName() + '#' + primKey; + String key = String.valueOf(event.getKey()); log.debug( "MyListener[" + name + "] - Visiting key " + key ); // String name = fqn.toString(); String token = ".functional."; diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/NaturalIdInvalidationTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/NaturalIdInvalidationTestCase.java index 2b1891de0bb0..dd6099b01031 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/NaturalIdInvalidationTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/NaturalIdInvalidationTestCase.java @@ -6,11 +6,14 @@ */ package org.hibernate.test.cache.infinispan.functional.cluster; +import javax.transaction.TransactionManager; +import java.util.Set; +import java.util.concurrent.Callable; + import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.criterion.Restrictions; import org.hibernate.test.cache.infinispan.functional.Citizen; import org.hibernate.test.cache.infinispan.functional.NaturalIdOnManyToOne; @@ -23,15 +26,8 @@ import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; import org.jboss.util.collection.ConcurrentSet; -import org.junit.After; import org.junit.Test; -import javax.transaction.TransactionManager; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Callable; - -import static org.infinispan.test.TestingUtil.tmpDirectory; import static org.infinispan.test.TestingUtil.withTx; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -263,8 +259,7 @@ public boolean isEmpty() { public void nodeVisited(CacheEntryVisitedEvent event) { log.debug( event.toString() ); if ( !event.isPre() ) { - NaturalIdCacheKey cacheKey = (NaturalIdCacheKey) event.getKey(); - visited.add(cacheKey.toString()); + visited.add(event.getKey().toString()); // Integer primKey = (Integer) cacheKey.getKey(); // String key = (String) cacheKey.getEntityOrRoleName() + '#' + primKey; // log.debug( "MyListener[" + name + "] - Visiting key " + key ); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/TestingKeyFactory.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/TestingKeyFactory.java new file mode 100644 index 000000000000..26c695d8b1be --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/TestingKeyFactory.java @@ -0,0 +1,61 @@ +/* + * 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.test.cache.infinispan.util; + +import java.io.Serializable; + +public class TestingKeyFactory { + + private TestingKeyFactory() { + //Not to be constructed + } + + public static Object generateEntityCacheKey(String id) { + return new TestingEntityCacheKey( id ); + } + + public static Object generateCollectionCacheKey(String id) { + return new TestingEntityCacheKey( id ); + } + + //For convenience implement both interfaces. + private static class TestingEntityCacheKey implements Serializable { + + private final String id; + + public TestingEntityCacheKey(String id) { + this.id = id; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TestingEntityCacheKey other = (TestingEntityCacheKey) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + } + +} diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseCollectionRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseCollectionRegionAccessStrategy.java index 92716139a50e..973b7dd5012d 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseCollectionRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseCollectionRegionAccessStrategy.java @@ -6,13 +6,17 @@ */ package org.hibernate.testing.cache; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * @author Strong Liu */ class BaseCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy { + private final CollectionRegionImpl region; BaseCollectionRegionAccessStrategy(CollectionRegionImpl region) { @@ -33,4 +37,15 @@ protected boolean isDefaultMinimalPutOverride() { public CollectionRegion getRegion() { return region; } + + @Override + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } + } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseEntityRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseEntityRegionAccessStrategy.java index 920f86c8b7d0..57023e59ba49 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseEntityRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseEntityRegionAccessStrategy.java @@ -7,21 +7,24 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * @author Strong Liu */ class BaseEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy { + private final EntityRegionImpl region; BaseEntityRegionAccessStrategy(EntityRegionImpl region) { this.region = region; } - @Override public EntityRegion getRegion() { return region; @@ -58,4 +61,14 @@ protected BaseGeneralDataRegion getInternalRegion() { protected boolean isDefaultMinimalPutOverride() { return region.getSettings().isMinimalPutsEnabled(); } + + @Override + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseNaturalIdRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseNaturalIdRegionAccessStrategy.java index 3afdcda7afb1..560b46a31f90 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseNaturalIdRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseNaturalIdRegionAccessStrategy.java @@ -7,9 +7,12 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +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; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * @author Eric Dalquist @@ -55,4 +58,14 @@ public boolean afterUpdate(Object key, Object value, SoftLock lock) throws Cache BaseNaturalIdRegionAccessStrategy(NaturalIdRegionImpl region) { this.region = region; } + + @Override + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseRegionAccessStrategy.java index 2f52739736c5..7b277e026fc1 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/BaseRegionAccessStrategy.java @@ -9,15 +9,14 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.access.RegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; - import org.jboss.logging.Logger; /** * @author Strong Liu */ abstract class BaseRegionAccessStrategy implements RegionAccessStrategy { - private static final Logger LOG = Logger.getLogger( BaseRegionAccessStrategy.class ); + private static final Logger LOG = Logger.getLogger( BaseRegionAccessStrategy.class ); protected abstract BaseGeneralDataRegion getInternalRegion(); diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyEntityRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyEntityRegionAccessStrategy.java index 73c00984c7c1..18bfb5d5bf5f 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyEntityRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyEntityRegionAccessStrategy.java @@ -8,7 +8,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.access.SoftLock; - import org.jboss.logging.Logger; /** diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteCollectionRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteCollectionRegionAccessStrategy.java index 7d710343f4be..d73eeb81d7e1 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteCollectionRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteCollectionRegionAccessStrategy.java @@ -8,8 +8,11 @@ import java.util.Comparator; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.CollectionPersister; /** * @author Strong Liu @@ -42,4 +45,14 @@ protected boolean isDefaultMinimalPutOverride() { public CollectionRegion getRegion() { return region; } + + @Override + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteEntityRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteEntityRegionAccessStrategy.java index ee94d910c6f3..42283092b776 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteEntityRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteEntityRegionAccessStrategy.java @@ -9,9 +9,12 @@ import java.util.Comparator; import org.hibernate.cache.CacheException; +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; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * @author Strong Liu @@ -103,4 +106,14 @@ Comparator getVersionComparator() { public EntityRegion getRegion() { return region; } + + @Override + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + + @Override + public Object getCacheKeyId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteNaturalIdRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteNaturalIdRegionAccessStrategy.java index 476cd77347c6..caefe030e71a 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteNaturalIdRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadWriteNaturalIdRegionAccessStrategy.java @@ -9,9 +9,12 @@ import java.util.Comparator; import org.hibernate.cache.CacheException; +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; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; /** * @author Eric Dalquist @@ -101,4 +104,14 @@ protected boolean isDefaultMinimalPutOverride() { public NaturalIdRegion getRegion() { return region; } + + @Override + public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } }