From 747af00522d0644574fb706e39da16d0a6be7e87 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Sat, 23 May 2015 15:48:40 +0200 Subject: [PATCH 1/7] HHH-9840 Refactor org.hibernate.cache.spi.CacheKey into an interface --- .../internal/OldCacheKeyImplementation.java | 104 ++++++++++++++++++ .../org/hibernate/cache/spi/CacheKey.java | 83 +------------- .../internal/AbstractSessionImpl.java | 3 +- .../org/hibernate/internal/CacheImpl.java | 5 +- 4 files changed, 114 insertions(+), 81 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java new file mode 100644 index 000000000000..453f1bce8f3a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java @@ -0,0 +1,104 @@ +/* + * 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 java.io.Serializable; + +import org.hibernate.cache.spi.CacheKey; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.util.compare.EqualsHelper; +import org.hibernate.type.Type; + +/** + * 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 interface. + * + * @author Gavin King + * @author Steve Ebersole + */ +@Deprecated +public class OldCacheKeyImplementation implements CacheKey, Serializable { + private final Serializable key; + private final Type type; + private final String entityOrRoleName; + private final String tenantId; + private final int hashCode; + + /** + * Construct a new key for a collection or entity instance. + * Note that an entity name should always be the root entity + * name, not a subclass entity name. + * + * @param id The identifier associated with the cached data + * @param type The Hibernate type mapping + * @param entityOrRoleName The entity or collection-role name. + * @param tenantId The tenant identifier associated this data. + * @param factory The session factory for which we are caching + */ + public OldCacheKeyImplementation( + final Serializable id, + final Type type, + final String entityOrRoleName, + final String tenantId, + final SessionFactoryImplementor factory) { + this.key = id; + this.type = type; + this.entityOrRoleName = entityOrRoleName; + this.tenantId = tenantId; + this.hashCode = calculateHashCode( type, factory ); + } + + private int calculateHashCode(Type type, SessionFactoryImplementor factory) { + int result = type.getHashCode( key, 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; + } + + @Override + public boolean equals(Object other) { + if ( other == null ) { + return false; + } + if ( this == other ) { + return true; + } + 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 OldCacheKeyImplementation that = (OldCacheKeyImplementation) other; + return EqualsHelper.equals( entityOrRoleName, that.entityOrRoleName ) + && type.isEqual( key, that.key ) + && EqualsHelper.equals( tenantId, that.tenantId ); + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public String toString() { + // Used to be required for OSCache + return entityOrRoleName + '#' + key.toString(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java index f33d311af7ca..663266781c21 100755 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java @@ -8,10 +8,6 @@ import java.io.Serializable; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.internal.util.compare.EqualsHelper; -import org.hibernate.type.Type; - /** * 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(). @@ -19,81 +15,12 @@ * @author Gavin King * @author Steve Ebersole */ -public class CacheKey implements Serializable { - private final Serializable key; - private final Type type; - private final String entityOrRoleName; - private final String tenantId; - private final int hashCode; - - /** - * Construct a new key for a collection or entity instance. - * Note that an entity name should always be the root entity - * name, not a subclass entity name. - * - * @param id The identifier associated with the cached data - * @param type The Hibernate type mapping - * @param entityOrRoleName The entity or collection-role name. - * @param tenantId The tenant identifier associated this data. - * @param factory The session factory for which we are caching - */ - public CacheKey( - final Serializable id, - final Type type, - final String entityOrRoleName, - final String tenantId, - final SessionFactoryImplementor factory) { - this.key = id; - this.type = type; - this.entityOrRoleName = entityOrRoleName; - this.tenantId = tenantId; - this.hashCode = calculateHashCode( type, factory ); - } - - private int calculateHashCode(Type type, SessionFactoryImplementor factory) { - int result = type.getHashCode( key, 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 interface CacheKey { + + public Serializable getKey(); - @Override - public boolean equals(Object other) { - if ( other == null ) { - return false; - } - if ( this == other ) { - return true; - } - if ( hashCode != other.hashCode() || !( other instanceof CacheKey ) ) { - //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; - return EqualsHelper.equals( entityOrRoleName, that.entityOrRoleName ) - && type.isEqual( key, that.key ) - && EqualsHelper.equals( tenantId, that.tenantId ); - } + public String getEntityOrRoleName(); - @Override - public int hashCode() { - return hashCode; - } + public String getTenantId(); - @Override - public String toString() { - // Used to be required for OSCache - return entityOrRoleName + '#' + key.toString(); - } } 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..4df5a2d57fe9 100755 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java @@ -26,6 +26,7 @@ import org.hibernate.SharedSessionContract; import org.hibernate.Transaction; import org.hibernate.boot.spi.SessionFactoryOptions; +import org.hibernate.cache.internal.OldCacheKeyImplementation; import org.hibernate.cache.spi.CacheKey; import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; @@ -338,7 +339,7 @@ public EntityKey generateEntityKey(Serializable id, EntityPersister persister) { @Override public CacheKey generateCacheKey(Serializable id, Type type, String entityOrRoleName) { - return new CacheKey( id, type, entityOrRoleName, getTenantIdentifier(), getFactory() ); + return new OldCacheKeyImplementation( id, type, entityOrRoleName, getTenantIdentifier(), getFactory() ); } private transient JdbcConnectionAccess jdbcConnectionAccess; 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..fa58f8582301 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java @@ -14,6 +14,7 @@ import org.hibernate.HibernateException; import org.hibernate.boot.spi.SessionFactoryOptions; +import org.hibernate.cache.internal.OldCacheKeyImplementation; import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.Region; @@ -97,7 +98,7 @@ public void evictEntity(String entityName, Serializable identifier) { } private CacheKey buildCacheKey(Serializable identifier, EntityPersister p) { - return new CacheKey( + return new OldCacheKeyImplementation( identifier, p.getIdentifierType(), p.getRootEntityName(), @@ -175,7 +176,7 @@ public void evictCollection(String role, Serializable ownerIdentifier) { } private CacheKey buildCacheKey(Serializable ownerIdentifier, CollectionPersister p) { - return new CacheKey( + return new OldCacheKeyImplementation( ownerIdentifier, p.getKeyType(), p.getRole(), From 56f2a4a37fab8cfcc10722b31b5e913806e7421c Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Thu, 28 May 2015 00:26:57 +0100 Subject: [PATCH 2/7] HHH-9840 Allow 2nd level cache implementations to customize the various key implementations --- .../action/internal/CollectionAction.java | 38 +++-- .../action/internal/EntityDeleteAction.java | 23 ++- .../action/internal/EntityInsertAction.java | 43 +++-- .../action/internal/EntityUpdateAction.java | 49 +++--- .../internal/CollectionCacheInvalidator.java | 17 +- .../internal/DefaultCacheKeysFactory.java | 59 +++++++ .../internal/OldCacheKeyImplementation.java | 21 ++- .../cache/internal/OldNaturalIdCacheKey.java | 160 ++++++++++++++++++ .../org/hibernate/cache/spi/CacheKey.java | 10 +- .../cache/spi/CollectionCacheKey.java | 26 +++ .../hibernate/cache/spi/EntityCacheKey.java | 26 +++ .../cache/spi/NaturalIdCacheKey.java | 145 +--------------- .../CollectionRegionAccessStrategy.java | 18 +- .../access/EntityRegionAccessStrategy.java | 34 +++- .../access/NaturalIdRegionAccessStrategy.java | 29 +++- .../spi/access/RegionAccessStrategy.java | 19 ++- .../engine/internal/CacheHelper.java | 29 +--- .../internal/NaturalIdXrefDelegate.java | 8 +- .../internal/StatefulPersistenceContext.java | 6 +- .../engine/internal/TwoPhaseLoad.java | 18 +- .../internal/CollectionLoadContext.java | 14 +- .../hibernate/engine/spi/BatchFetchQueue.java | 30 ++-- .../engine/spi/SessionDelegatorBaseImpl.java | 7 - .../engine/spi/SessionImplementor.java | 12 -- .../AbstractLockUpgradeEventListener.java | 26 ++- ...aultInitializeCollectionEventListener.java | 10 +- .../internal/DefaultLoadEventListener.java | 27 +-- .../internal/DefaultRefreshEventListener.java | 13 +- .../internal/AbstractSessionImpl.java | 8 - .../org/hibernate/internal/CacheImpl.java | 55 +++--- .../internal/StatelessSessionImpl.java | 8 +- .../java/org/hibernate/loader/Loader.java | 19 ++- .../entity/AbstractEntityPersister.java | 10 +- ...currentSecondLevelCacheStatisticsImpl.java | 4 +- .../cache/spi/NaturalIdCacheKeyTest.java | 5 +- .../test/filter/DynamicFilterTest.java | 24 +-- ...opAwareCollectionRegionAccessStrategy.java | 25 ++- ...onstopAwareEntityRegionAccessStrategy.java | 33 ++-- ...topAwareNaturalIdRegionAccessStrategy.java | 31 ++-- .../AbstractEhcacheAccessStrategy.java | 33 +++- ...bstractReadWriteEhcacheAccessStrategy.java | 15 +- ...EhcacheCollectionRegionAccessStrategy.java | 13 +- ...riteEhcacheEntityRegionAccessStrategy.java | 26 +-- ...eEhcacheNaturalIdRegionAccessStrategy.java | 24 +-- ...EhcacheCollectionRegionAccessStrategy.java | 11 +- ...OnlyEhcacheEntityRegionAccessStrategy.java | 19 ++- ...yEhcacheNaturalIdRegionAccessStrategy.java | 19 ++- ...EhcacheCollectionRegionAccessStrategy.java | 3 +- ...riteEhcacheEntityRegionAccessStrategy.java | 11 +- ...eEhcacheNaturalIdRegionAccessStrategy.java | 11 +- ...EhcacheCollectionRegionAccessStrategy.java | 17 +- ...onalEhcacheEntityRegionAccessStrategy.java | 21 +-- ...lEhcacheNaturalIdRegionAccessStrategy.java | 21 +-- .../collection/TransactionalAccess.java | 25 ++- .../infinispan/entity/ReadOnlyAccess.java | 5 +- .../entity/TransactionalAccess.java | 34 ++-- .../infinispan/naturalid/ReadOnlyAccess.java | 7 +- .../naturalid/TransactionalAccess.java | 31 ++-- ...bstractEntityCollectionRegionTestCase.java | 4 +- .../AbstractGeneralDataRegionTestCase.java | 10 +- .../AbstractRegionImplTestCase.java | 7 +- ...ollectionRegionAccessStrategyTestCase.java | 12 +- .../CollectionRegionImplTestCase.java | 8 +- .../TransactionalExtraAPITestCase.java | 5 +- ...actEntityRegionAccessStrategyTestCase.java | 15 +- .../AbstractReadOnlyAccessTestCase.java | 10 +- .../AbstractTransactionalAccessTestCase.java | 6 +- .../entity/EntityRegionImplTestCase.java | 8 +- .../entity/TransactionalExtraAPITestCase.java | 5 +- .../EntityCollectionInvalidationTestCase.java | 8 +- .../infinispan/util/TestingKeyFactory.java | 84 +++++++++ .../AbstractReadWriteAccessStrategy.java | 11 +- .../BaseCollectionRegionAccessStrategy.java | 15 +- .../cache/BaseEntityRegionAccessStrategy.java | 24 ++- .../BaseNaturalIdRegionAccessStrategy.java | 23 ++- .../cache/BaseRegionAccessStrategy.java | 20 +-- ...adWriteCollectionRegionAccessStrategy.java | 5 +- ...ctReadWriteEntityRegionAccessStrategy.java | 13 +- ...eadWriteNaturalIdRegionAccessStrategy.java | 11 +- .../ReadOnlyEntityRegionAccessStrategy.java | 12 +- ...ReadOnlyNaturalIdRegionAccessStrategy.java | 3 +- ...adWriteCollectionRegionAccessStrategy.java | 13 +- .../ReadWriteEntityRegionAccessStrategy.java | 21 ++- ...eadWriteNaturalIdRegionAccessStrategy.java | 19 ++- ...ctionalCollectionRegionAccessStrategy.java | 3 +- ...ansactionalEntityRegionAccessStrategy.java | 9 +- ...actionalNaturalIdRegionAccessStrategy.java | 3 +- 87 files changed, 1186 insertions(+), 686 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java mode change 100755 => 100644 hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cache/spi/CollectionCacheKey.java create mode 100755 hibernate-core/src/main/java/org/hibernate/cache/spi/EntityCacheKey.java create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/TestingKeyFactory.java 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..3c070df5baa1 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,8 @@ 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.CollectionCacheKey; +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 +77,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 CollectionCacheKey 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 +130,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 CollectionCacheKey ck = cache.generateCacheKey( key, - persister.getKeyType(), - persister.getRole() + persister, + session.getFactory(), + session.getTenantIdentifier() ); - persister.getCacheAccessStrategy().remove( ck ); + cache.remove( ck ); } } @@ -169,12 +174,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 CollectionCacheKey ck = cache.generateCacheKey( key, - persister.getKeyType(), - persister.getRole() + persister, + session.getFactory(), + session.getTenantIdentifier() ); - persister.getCacheAccessStrategy().unlockItem( ck, lock ); + cache.unlockItem( ck, lock ); } } @@ -191,8 +198,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..d2ca5f9b8f56 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,8 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +85,11 @@ public void execute() throws HibernateException { version = persister.getVersion( instance ); } - final CacheKey ck; + final EntityCacheKey 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 +186,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 EntityCacheKey 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..4061fa29bc5b 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,14 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +88,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 +104,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 +117,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 EntityCacheKey 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 +138,7 @@ public void execute() throws HibernateException { markExecuted(); } - private boolean cacheInsert(EntityPersister persister, CacheKey ck) { + private boolean cacheInsert(EntityPersister persister, EntityCacheKey ck) { try { getSession().getEventListenerManager().cachePutStart(); return persister.getCacheAccessStrategy().insert( ck, cacheEntry, version ); @@ -207,24 +211,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 EntityCacheKey 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, EntityCacheKey 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..4bffb3afb0e0 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,14 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +118,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 +127,16 @@ public void execute() throws HibernateException { previousVersion = persister.getVersion( instance ); } - final CacheKey ck; + final EntityCacheKey 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 +156,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 +216,7 @@ public void execute() throws HibernateException { } } - private boolean cacheUpdate(EntityPersister persister, Object previousVersion, CacheKey ck) { + private boolean cacheUpdate(EntityPersister persister, Object previousVersion, EntityCacheKey ck) { try { getSession().getEventListenerManager().cachePutStart(); return persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion ); @@ -307,34 +311,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 EntityCacheKey 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, EntityCacheKey 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..83b5254a2aa1 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,8 @@ import java.util.Set; import org.hibernate.boot.Metadata; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.CollectionCacheKey; +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 +137,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(); + CollectionCacheKey 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..fcc060dd6fd8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java @@ -0,0 +1,59 @@ +/* + * 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 java.io.Serializable; + +import org.hibernate.cache.spi.CollectionCacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +import org.hibernate.cache.spi.NaturalIdCacheKey; +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 CollectionCacheKey createCollectionKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return new OldCacheKeyImplementation( id, persister.getKeyType(), persister.getRole(), tenantIdentifier, factory ); + } + + public static EntityCacheKey createEntityKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return new OldCacheKeyImplementation( id, persister.getIdentifierType(), persister.getRootEntityName(), tenantIdentifier, factory ); + } + + public static NaturalIdCacheKey createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return new OldNaturalIdCacheKey( naturalIdValues, persister, session ); + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java index 453f1bce8f3a..2b2a00c2cebe 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java @@ -8,7 +8,8 @@ import java.io.Serializable; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.CollectionCacheKey; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.compare.EqualsHelper; import org.hibernate.type.Type; @@ -18,13 +19,13 @@ * 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 interface. + * Temporarily maintained as a reference while all components catch up with the refactoring to the caching interfaces. * * @author Gavin King * @author Steve Ebersole */ @Deprecated -public class OldCacheKeyImplementation implements CacheKey, Serializable { +final class OldCacheKeyImplementation implements EntityCacheKey, CollectionCacheKey, Serializable { private final Serializable key; private final Type type; private final String entityOrRoleName; @@ -42,7 +43,7 @@ public class OldCacheKeyImplementation implements CacheKey, Serializable { * @param tenantId The tenant identifier associated this data. * @param factory The session factory for which we are caching */ - public OldCacheKeyImplementation( + OldCacheKeyImplementation( final Serializable id, final Type type, final String entityOrRoleName, @@ -61,14 +62,24 @@ private int calculateHashCode(Type type, SessionFactoryImplementor factory) { return result; } + @Override public Serializable getKey() { return key; } - public String getEntityOrRoleName() { + @Override + public String getEntityName() { + //defined exclusively on EntityCacheKey return entityOrRoleName; } + @Override + public String getCollectionRole() { + //defined exclusively on CollectionCacheKey + return entityOrRoleName; + } + + @Override public String getTenantId() { return tenantId; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java new file mode 100644 index 000000000000..8d3ca82f5623 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java @@ -0,0 +1,160 @@ +/* + * 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 java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.Arrays; + +import org.hibernate.cache.spi.NaturalIdCacheKey; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.ValueHolder; +import org.hibernate.internal.util.compare.EqualsHelper; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.EntityType; +import org.hibernate.type.Type; + +/** + * 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 +public class OldNaturalIdCacheKey implements NaturalIdCacheKey, Serializable { + private final Serializable[] naturalIdValues; + private final String entityName; + private final String tenantId; + private final int hashCode; + // "transient" is important here -- NaturalIdCacheKey needs to be Serializable + private transient ValueHolder toString; + + /** + * Construct a new key for a caching natural identifier resolutions into the second level cache. + * + * @param naturalIdValues The naturalIdValues associated with the cached data + * @param persister The persister for the entity + * @param session The originating session + */ + public OldNaturalIdCacheKey( + final Object[] naturalIdValues, + final EntityPersister persister, + final SessionImplementor session) { + + this.entityName = persister.getRootEntityName(); + this.tenantId = session.getTenantIdentifier(); + + this.naturalIdValues = new Serializable[naturalIdValues.length]; + + final SessionFactoryImplementor factory = session.getFactory(); + final int[] naturalIdPropertyIndexes = persister.getNaturalIdentifierProperties(); + final Type[] propertyTypes = persister.getPropertyTypes(); + + final int prime = 31; + int result = 1; + result = prime * result + ( ( this.entityName == null ) ? 0 : this.entityName.hashCode() ); + result = prime * result + ( ( this.tenantId == null ) ? 0 : this.tenantId.hashCode() ); + for ( int i = 0; i < naturalIdValues.length; i++ ) { + final int naturalIdPropertyIndex = naturalIdPropertyIndexes[i]; + final Type type = propertyTypes[naturalIdPropertyIndex]; + final Object value = naturalIdValues[i]; + + result = prime * result + (value != null ? type.getHashCode( value, factory ) : 0); + + // The natural id may not be fully resolved in some situations. See HHH-7513 for one of them + // (re-attaching a mutable natural id uses a database snapshot and hydration does not resolve associations). + // TODO: The snapshot should probably be revisited at some point. Consider semi-resolving, hydrating, etc. + if (type instanceof EntityType && type.getSemiResolvedType( factory ).getReturnedClass().isInstance( value )) { + this.naturalIdValues[i] = (Serializable) value; + } + else { + this.naturalIdValues[i] = type.disassemble( value, session, null ); + } + } + + this.hashCode = result; + initTransients(); + } + + private void initTransients() { + this.toString = new ValueHolder( + new ValueHolder.DeferredInitializer() { + @Override + public String initialize() { + //Complex toString is needed as naturalIds for entities are not simply based on a single value like primary keys + //the only same way to differentiate the keys is to included the disassembled values in the string. + final StringBuilder toStringBuilder = new StringBuilder( entityName ).append( "##NaturalId[" ); + for ( int i = 0; i < naturalIdValues.length; i++ ) { + toStringBuilder.append( naturalIdValues[i] ); + if ( i + 1 < naturalIdValues.length ) { + toStringBuilder.append( ", " ); + } + } + toStringBuilder.append( "]" ); + + return toStringBuilder.toString(); + } + } + ); + } + + @SuppressWarnings( {"UnusedDeclaration"}) + public String getEntityName() { + return entityName; + } + + @SuppressWarnings( {"UnusedDeclaration"}) + public String getTenantId() { + return tenantId; + } + + @SuppressWarnings( {"UnusedDeclaration"}) + public Serializable[] getNaturalIdValues() { + return naturalIdValues; + } + + @Override + public String toString() { + return toString.getValue(); + } + + @Override + public int hashCode() { + return this.hashCode; + } + + @Override + public boolean equals(Object o) { + if ( o == null ) { + return false; + } + if ( this == o ) { + return true; + } + + 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 OldNaturalIdCacheKey other = (OldNaturalIdCacheKey) o; + return EqualsHelper.equals( entityName, other.entityName ) + && EqualsHelper.equals( tenantId, other.tenantId ) + && Arrays.deepEquals( this.naturalIdValues, other.naturalIdValues ); + } + + private void readObject(ObjectInputStream ois) + throws ClassNotFoundException, IOException { + ois.defaultReadObject(); + initTransients(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java old mode 100755 new mode 100644 index 663266781c21..d6583060d411 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java @@ -6,21 +6,13 @@ */ package org.hibernate.cache.spi; -import java.io.Serializable; - /** - * Allows multiple entity classes / collection roles to be stored in the same cache region. Also allows for composite + * Allows multiple entity roles to be stored in the same cache region. Also allows for composite * keys which do not properly implement equals()/hashCode(). * * @author Gavin King * @author Steve Ebersole */ public interface CacheKey { - - public Serializable getKey(); - - public String getEntityOrRoleName(); - - public String getTenantId(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CollectionCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CollectionCacheKey.java new file mode 100644 index 000000000000..7a9154b7954c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CollectionCacheKey.java @@ -0,0 +1,26 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.cache.spi; + +import java.io.Serializable; + +/** + * Allows multiple collection roles to be stored in the same cache region. Also allows for composite + * keys which do not properly implement equals()/hashCode(). + * + * @author Sanne Grinovero + * @since 5.0 + */ +public interface CollectionCacheKey extends CacheKey { + + public Serializable getKey(); + + public String getCollectionRole(); + + public String getTenantId(); + +} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/EntityCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/EntityCacheKey.java new file mode 100755 index 000000000000..cee5a9319be1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/EntityCacheKey.java @@ -0,0 +1,26 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.cache.spi; + +import java.io.Serializable; + +/** + * Allows multiple entity roles to be stored in the same cache region. Also allows for composite + * keys which do not properly implement equals()/hashCode(). + * + * @author Gavin King + * @author Steve Ebersole + */ +public interface EntityCacheKey extends CacheKey { + + public Serializable getKey(); + + public String getEntityName(); + + public String getTenantId(); + +} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java index eb1e2a70665d..0f22f37e7baf 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java @@ -6,151 +6,18 @@ */ package org.hibernate.cache.spi; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.Arrays; - -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.internal.util.ValueHolder; -import org.hibernate.internal.util.compare.EqualsHelper; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.type.EntityType; -import org.hibernate.type.Type; - /** * Defines a key for caching natural identifier resolutions into the second level cache. * - * @author Eric Dalquist - * @author Steve Ebersole + * @author Sanne Grinovero + * @since 5.0 */ -public class NaturalIdCacheKey implements Serializable { - private final Serializable[] naturalIdValues; - private final String entityName; - private final String tenantId; - private final int hashCode; - // "transient" is important here -- NaturalIdCacheKey needs to be Serializable - private transient ValueHolder toString; - - /** - * 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( - final Object[] naturalIdValues, - final EntityPersister persister, - final SessionImplementor session) { - - this.entityName = persister.getRootEntityName(); - this.tenantId = session.getTenantIdentifier(); - - this.naturalIdValues = new Serializable[naturalIdValues.length]; - - final SessionFactoryImplementor factory = session.getFactory(); - final int[] naturalIdPropertyIndexes = persister.getNaturalIdentifierProperties(); - final Type[] propertyTypes = persister.getPropertyTypes(); - - final int prime = 31; - int result = 1; - result = prime * result + ( ( this.entityName == null ) ? 0 : this.entityName.hashCode() ); - result = prime * result + ( ( this.tenantId == null ) ? 0 : this.tenantId.hashCode() ); - for ( int i = 0; i < naturalIdValues.length; i++ ) { - final int naturalIdPropertyIndex = naturalIdPropertyIndexes[i]; - final Type type = propertyTypes[naturalIdPropertyIndex]; - final Object value = naturalIdValues[i]; - - result = prime * result + (value != null ? type.getHashCode( value, factory ) : 0); - - // The natural id may not be fully resolved in some situations. See HHH-7513 for one of them - // (re-attaching a mutable natural id uses a database snapshot and hydration does not resolve associations). - // TODO: The snapshot should probably be revisited at some point. Consider semi-resolving, hydrating, etc. - if (type instanceof EntityType && type.getSemiResolvedType( factory ).getReturnedClass().isInstance( value )) { - this.naturalIdValues[i] = (Serializable) value; - } - else { - this.naturalIdValues[i] = type.disassemble( value, session, null ); - } - } - - this.hashCode = result; - initTransients(); - } - - private void initTransients() { - this.toString = new ValueHolder( - new ValueHolder.DeferredInitializer() { - @Override - public String initialize() { - //Complex toString is needed as naturalIds for entities are not simply based on a single value like primary keys - //the only same way to differentiate the keys is to included the disassembled values in the string. - final StringBuilder toStringBuilder = new StringBuilder( entityName ).append( "##NaturalId[" ); - for ( int i = 0; i < naturalIdValues.length; i++ ) { - toStringBuilder.append( naturalIdValues[i] ); - if ( i + 1 < naturalIdValues.length ) { - toStringBuilder.append( ", " ); - } - } - toStringBuilder.append( "]" ); - - return toStringBuilder.toString(); - } - } - ); - } - - @SuppressWarnings( {"UnusedDeclaration"}) - public String getEntityName() { - return entityName; - } - - @SuppressWarnings( {"UnusedDeclaration"}) - public String getTenantId() { - return tenantId; - } - - @SuppressWarnings( {"UnusedDeclaration"}) - public Serializable[] getNaturalIdValues() { - return naturalIdValues; - } - - @Override - public String toString() { - return toString.getValue(); - } - - @Override - public int hashCode() { - return this.hashCode; - } +public interface NaturalIdCacheKey extends CacheKey { - @Override - public boolean equals(Object o) { - if ( o == null ) { - return false; - } - if ( this == o ) { - return true; - } + String getEntityName(); - if ( hashCode != o.hashCode() || !( o instanceof NaturalIdCacheKey ) ) { - //hashCode is part of this check since it is pre-calculated and hash must match for equals to be true - return false; - } + Object[] getNaturalIdValues(); - final NaturalIdCacheKey other = (NaturalIdCacheKey) o; - return EqualsHelper.equals( entityName, other.entityName ) - && EqualsHelper.equals( tenantId, other.tenantId ) - && Arrays.deepEquals( this.naturalIdValues, other.naturalIdValues ); - } + String getTenantId(); - private void readObject(ObjectInputStream ois) - throws ClassNotFoundException, IOException { - ois.defaultReadObject(); - initTransients(); - } } 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..8813d6a2cdda 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 @@ -6,7 +6,12 @@ */ package org.hibernate.cache.spi.access; +import java.io.Serializable; + +import org.hibernate.cache.spi.CollectionCacheKey; 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 @@ -21,7 +26,18 @@ * @author Gavin King * @author Steve Ebersole */ -public interface CollectionRegionAccessStrategy extends RegionAccessStrategy { +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 CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier); /** * 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..a47eedfe5593 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 @@ -6,8 +6,13 @@ */ package org.hibernate.cache.spi.access; +import java.io.Serializable; + import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.EntityCacheKey; 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 +30,18 @@ * @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 EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier); /** * Get the wrapped entity cache region @@ -43,9 +59,9 @@ 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; + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException; /** * Called after an item has been inserted (after the transaction completes), @@ -56,9 +72,9 @@ 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; + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException; /** * Called after an item has been updated (before the transaction completes), @@ -70,9 +86,9 @@ 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; + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException; /** * Called after an item has been updated (after the transaction completes), @@ -85,7 +101,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; + public boolean afterUpdate(EntityCacheKey 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..044d51829ea8 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 @@ -7,7 +7,10 @@ package org.hibernate.cache.spi.access; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.NaturalIdCacheKey; 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 @@ -34,7 +37,17 @@ * @author Steve Ebersole * @author Eric Dalquist */ -public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy { +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 NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session); /** * Get the wrapped naturalId cache region @@ -51,9 +64,9 @@ 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; + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException; /** * Called after an item has been inserted (after the transaction completes), @@ -63,9 +76,9 @@ 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; + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException; /** * Called after an item has been updated (before the transaction completes), @@ -75,9 +88,9 @@ 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; + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException; /** * Called after an item has been updated (after the transaction completes), @@ -90,5 +103,5 @@ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy { * @return Were the contents of the cache actual changed by this operation? * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException; + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) 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..91ccd03f5638 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,14 +6,17 @@ */ package org.hibernate.cache.spi.access; + import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.CacheKey; /** * Base access strategy for all regions. * * @author Gail Badner */ -public interface RegionAccessStrategy { +public interface RegionAccessStrategy { + /** * Attempt to retrieve an object from the cache. Mainly used in attempting * to resolve entities/collections from the second level cache. @@ -23,7 +26,7 @@ public interface RegionAccessStrategy { * @return the cached object or null * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - Object get(Object key, long txTimestamp) throws CacheException; + Object get(T key, long txTimestamp) throws CacheException; /** * Attempt to cache an object, after loading from the database. @@ -36,7 +39,7 @@ public interface RegionAccessStrategy { * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ boolean putFromLoad( - Object key, + T key, Object value, long txTimestamp, Object version) throws CacheException; @@ -54,7 +57,7 @@ boolean putFromLoad( * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ boolean putFromLoad( - Object key, + T key, Object value, long txTimestamp, Object version, @@ -73,7 +76,7 @@ boolean putFromLoad( * @return A representation of our lock on the item; or null. * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - SoftLock lockItem(Object key, Object version) throws CacheException; + SoftLock lockItem(T key, Object version) throws CacheException; /** * Lock the entire region @@ -92,7 +95,7 @@ boolean putFromLoad( * @param lock The lock previously obtained from {@link #lockItem} * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - void unlockItem(Object key, SoftLock lock) throws CacheException; + void unlockItem(T key, SoftLock lock) throws CacheException; /** * Called after we have finished the attempted invalidation of the entire @@ -110,7 +113,7 @@ boolean putFromLoad( * @param key The key of the item to remove * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - void remove(Object key) throws CacheException; + void remove(T key) throws CacheException; /** * Called to evict data from the entire region @@ -126,7 +129,7 @@ boolean putFromLoad( * @param key The key of the item to remove * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - void evict(Object key) throws CacheException; + void evict(T key) throws CacheException; /** * Forcibly evict all items from the cache immediately without regard for transaction 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..06cfcc0cb8d0 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 @@ -9,44 +9,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 CacheHelper() { } - private static Serializable fromSharedCache( + public static Serializable fromSharedCache( SessionImplementor session, - Object cacheKey, - RegionAccessStrategy cacheAccessStrategy) { + T 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..bc1f9f504099 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 @@ -110,12 +110,12 @@ public Object[] removeNaturalIdCrossReference(EntityPersister persister, Seriali if ( persister.hasNaturalIdCache() ) { final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister .getNaturalIdCacheAccessStrategy(); - final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session() ); + final NaturalIdCacheKey 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 NaturalIdCacheKey sessionNaturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( sessionCachedNaturalIdValues, persister, session() ); naturalIdCacheAccessStrategy.evict( sessionNaturalIdCacheKey ); } } @@ -239,9 +239,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 NaturalIdCacheKey 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..b6b1d8cec68f 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 @@ -1738,7 +1738,7 @@ private void managedSharedCacheEntries( Object[] previousNaturalIdValues, CachedNaturalIdValueSource source) { final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy(); - final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session ); + final NaturalIdCacheKey naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session ); final SessionFactoryImplementor factory = session.getFactory(); @@ -1793,7 +1793,7 @@ public void doAfterTransactionCompletion(boolean success, SessionImplementor ses break; } case UPDATE: { - final NaturalIdCacheKey previousCacheKey = new NaturalIdCacheKey( previousNaturalIdValues, persister, session ); + final NaturalIdCacheKey previousCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( previousNaturalIdValues, persister, session ); if ( naturalIdCacheKey.equals( previousCacheKey ) ) { // prevent identical re-caching, solves HHH-7309 return; @@ -1877,7 +1877,7 @@ public void removeSharedNaturalIdCrossReference(EntityPersister persister, Seria persister = locateProperPersister( persister ); final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy(); - final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session ); + final NaturalIdCacheKey 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 4781c6838193..1bbbd1148f63 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,13 @@ 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.EntityCacheKey; +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 +184,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 EntityCacheKey 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 +194,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 +202,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 +214,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..0d13051b8277 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,9 @@ import org.hibernate.CacheMode; import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.CollectionCacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +334,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 CollectionCacheKey cacheKey = cache.generateCacheKey( + lce.getKey(), + persister, + session.getFactory(), + session.getTenantIdentifier() + ); boolean isPutFromLoad = true; if ( persister.getElementType().isAssociationType() ) { @@ -349,7 +357,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..245b0ae98bcb 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,10 @@ import java.util.Map.Entry; import org.hibernate.EntityMode; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.CollectionCacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +204,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 EntityCacheKey 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 +320,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(); + CollectionCacheKey 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/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..bcf05f8147fe 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,8 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.ObjectDeletedException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +18,6 @@ import org.hibernate.internal.CoreLogging; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; - import org.jboss.logging.Logger; /** @@ -62,18 +62,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; + EntityCacheKey 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 +87,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..55bc6e10ff71 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,8 @@ import java.io.Serializable; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.CollectionCacheKey; +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 +117,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 CollectionCacheKey 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..23d8dfdc089b 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,8 @@ import org.hibernate.PersistentObjectException; import org.hibernate.TypeMismatchException; import org.hibernate.WrongClassException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +358,14 @@ protected Object lockAndLoad( final LoadEventListener.LoadType options, final SessionImplementor source) { SoftLock lock = null; - final CacheKey ck; + final EntityCacheKey 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 +379,7 @@ protected Object lockAndLoad( } finally { if ( persister.hasCache() ) { - persister.getCacheAccessStrategy().unlockItem( ck, lock ); + cache.unlockItem( ck, lock ); } } @@ -572,22 +575,24 @@ protected Object loadFromSecondLevelCache( } final SessionFactoryImplementor factory = source.getFactory(); - final CacheKey ck = source.generateCacheKey( + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + final EntityCacheKey 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..6ba772ef5970 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,8 @@ import org.hibernate.HibernateException; import org.hibernate.PersistentObjectException; import org.hibernate.UnresolvableObjectException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +137,14 @@ public void onRefresh(RefreshEvent event, Map refreshedAlready) { } if ( persister.hasCache() ) { - final CacheKey ck = source.generateCacheKey( + final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); + EntityCacheKey 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 4df5a2d57fe9..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,8 +26,6 @@ import org.hibernate.SharedSessionContract; import org.hibernate.Transaction; import org.hibernate.boot.spi.SessionFactoryOptions; -import org.hibernate.cache.internal.OldCacheKeyImplementation; -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; @@ -59,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 @@ -337,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 OldCacheKeyImplementation( 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 fa58f8582301..25fe30046314 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java @@ -14,12 +14,14 @@ import org.hibernate.HibernateException; import org.hibernate.boot.spi.SessionFactoryOptions; -import org.hibernate.cache.internal.OldCacheKeyImplementation; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.CollectionCacheKey; +import org.hibernate.cache.spi.EntityCacheKey; 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; @@ -74,8 +76,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(); + EntityCacheKey key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy + return cache.getRegion().contains( key ); + } + else { + return false; + } } @Override @@ -93,20 +101,12 @@ public void evictEntity(String entityName, Serializable identifier) { MessageHelper.infoString( p, identifier, sessionFactory ) ); } - p.getCacheAccessStrategy().evict( buildCacheKey( identifier, p ) ); + EntityRegionAccessStrategy cache = p.getCacheAccessStrategy(); + EntityCacheKey key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy + cache.evict( key ); } } - private CacheKey buildCacheKey(Serializable identifier, EntityPersister p) { - return new OldCacheKeyImplementation( - identifier, - p.getIdentifierType(), - p.getRootEntityName(), - null, // have to assume non tenancy - sessionFactory - ); - } - @Override public void evictEntityRegion(Class entityClass) { evictEntityRegion( entityClass.getName() ); @@ -156,8 +156,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(); + CollectionCacheKey key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy + return cache.getRegion().contains( key ); + } + else { + return false; + } } @Override @@ -170,21 +176,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(); + CollectionCacheKey key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy + cache.evict( key ); } } - private CacheKey buildCacheKey(Serializable ownerIdentifier, CollectionPersister p) { - return new OldCacheKeyImplementation( - 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/StatelessSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java index 404b572d1923..62f719e9ffd7 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,8 @@ import org.hibernate.StatelessSession; import org.hibernate.Transaction; import org.hibernate.UnresolvableObjectException; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +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 +271,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 EntityCacheKey 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..8a89ab38c011 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -32,9 +32,11 @@ import org.hibernate.Session; import org.hibernate.StaleObjectStateException; import org.hibernate.WrongClassException; +import org.hibernate.cache.spi.EntityCacheKey; 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 +1622,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 EntityCacheKey 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 964b32e22003..d0f527ee1fa2 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,7 @@ 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.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; @@ -906,8 +906,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 EntityCacheKey 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 +4270,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 EntityCacheKey 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/ConcurrentSecondLevelCacheStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentSecondLevelCacheStatisticsImpl.java index d7292d231f2a..8c4518352b24 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 @@ -11,7 +11,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicLong; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.Region; import org.hibernate.stat.SecondLevelCacheStatistics; @@ -60,7 +60,7 @@ public Map getEntries() { Iterator iter = region.toMap().entrySet().iterator(); while (iter.hasNext()) { Map.Entry me = (Map.Entry) iter.next(); - map.put(((CacheKey) me.getKey()).getKey(), me.getValue()); + map.put(((EntityCacheKey) me.getKey()).getKey(), me.getValue()); } return map; } 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..771c92fcf6fb 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 @@ -18,6 +18,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.entity.EntityPersister; @@ -58,8 +59,8 @@ public Object answer(InvocationOnMock invocation) throws Throwable { return invocation.getArguments()[0]; } }); - - final NaturalIdCacheKey key = new NaturalIdCacheKey(new Object[] {"a", "b", "c"}, entityPersister, sessionImplementor); + + final NaturalIdCacheKey key = DefaultCacheKeysFactory.createNaturalIdKey( new Object[] {"a", "b", "c"}, entityPersister, sessionImplementor ); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream(baos); 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..f28cf9c336c6 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,8 @@ import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.CollectionCacheKey; +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 +101,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(); + CollectionCacheKey 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 +117,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( + CollectionCacheKey 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..94b6457767b4 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 @@ -6,12 +6,18 @@ */ package org.hibernate.cache.ehcache.internal.nonstop; +import java.io.Serializable; + import net.sf.ehcache.constructs.nonstop.NonStopCacheException; import org.hibernate.cache.CacheException; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.CollectionCacheKey; 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 @@ -43,7 +49,7 @@ public CollectionRegion getRegion() { } @Override - public void evict(Object key) throws CacheException { + public void evict(CollectionCacheKey key) throws CacheException { try { actualStrategy.evict( key ); } @@ -63,7 +69,7 @@ public void evictAll() throws CacheException { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { try { return actualStrategy.get( key, txTimestamp ); } @@ -74,7 +80,7 @@ public Object get(Object key, long txTimestamp) throws CacheException { } @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheException { try { return actualStrategy.lockItem( key, version ); } @@ -96,7 +102,7 @@ public SoftLock lockRegion() throws CacheException { } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); @@ -108,7 +114,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version ); } @@ -119,7 +125,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public void remove(Object key) throws CacheException { + public void remove(CollectionCacheKey key) throws CacheException { try { actualStrategy.remove( key ); } @@ -139,7 +145,7 @@ public void removeAll() throws CacheException { } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { try { actualStrategy.unlockItem( key, lock ); } @@ -158,4 +164,9 @@ public void unlockRegion(SoftLock lock) throws CacheException { } } + @Override + public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + } 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..ca3795e1f949 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 @@ -6,12 +6,18 @@ */ package org.hibernate.cache.ehcache.internal.nonstop; +import java.io.Serializable; + import net.sf.ehcache.constructs.nonstop.NonStopCacheException; import org.hibernate.cache.CacheException; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.EntityCacheKey; 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 @@ -43,7 +49,7 @@ public EntityRegion getRegion() { } @Override - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { try { return actualStrategy.afterInsert( key, value, version ); } @@ -54,7 +60,7 @@ public boolean afterInsert(Object key, Object value, Object version) throws Cach } @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { try { return actualStrategy.afterUpdate( key, value, currentVersion, previousVersion, lock ); @@ -66,7 +72,7 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje } @Override - public void evict(Object key) throws CacheException { + public void evict(EntityCacheKey key) throws CacheException { try { actualStrategy.evict( key ); } @@ -86,7 +92,7 @@ public void evictAll() throws CacheException { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { try { return actualStrategy.get( key, txTimestamp ); } @@ -97,7 +103,7 @@ public Object get(Object key, long txTimestamp) throws CacheException { } @Override - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { try { return actualStrategy.insert( key, value, version ); } @@ -108,7 +114,7 @@ public boolean insert(Object key, Object value, Object version) throws CacheExce } @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheException { try { return actualStrategy.lockItem( key, version ); } @@ -130,7 +136,7 @@ public SoftLock lockRegion() throws CacheException { } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); @@ -142,7 +148,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version ); } @@ -153,7 +159,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public void remove(Object key) throws CacheException { + public void remove(EntityCacheKey key) throws CacheException { try { actualStrategy.remove( key ); } @@ -173,7 +179,7 @@ public void removeAll() throws CacheException { } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { try { actualStrategy.unlockItem( key, lock ); } @@ -193,7 +199,7 @@ public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { try { return actualStrategy.update( key, value, currentVersion, previousVersion ); @@ -203,4 +209,9 @@ public boolean update(Object key, Object value, Object currentVersion, Object pr return false; } } + + @Override + public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } } 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..22202fe7e341 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 @@ -9,9 +9,13 @@ import net.sf.ehcache.constructs.nonstop.NonStopCacheException; import org.hibernate.cache.CacheException; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.NaturalIdCacheKey; 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 @@ -38,7 +42,7 @@ public NonstopAwareNaturalIdRegionAccessStrategy( } @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { try { return actualStrategy.insert( key, value ); } @@ -49,7 +53,7 @@ public boolean insert(Object key, Object value) throws CacheException { } @Override - public boolean afterInsert(Object key, Object value) throws CacheException { + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { try { return actualStrategy.afterInsert( key, value ); } @@ -60,7 +64,7 @@ public boolean afterInsert(Object key, Object value) throws CacheException { } @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { try { return actualStrategy.update( key, value ); } @@ -71,7 +75,7 @@ public boolean update(Object key, Object value) throws CacheException { } @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { try { return actualStrategy.afterUpdate( key, value, lock ); } @@ -87,7 +91,7 @@ public NaturalIdRegion getRegion() { } @Override - public void evict(Object key) throws CacheException { + public void evict(NaturalIdCacheKey key) throws CacheException { try { actualStrategy.evict( key ); } @@ -107,7 +111,7 @@ public void evictAll() throws CacheException { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { try { return actualStrategy.get( key, txTimestamp ); } @@ -118,7 +122,7 @@ public Object get(Object key, long txTimestamp) throws CacheException { } @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheException { try { return actualStrategy.lockItem( key, version ); } @@ -140,7 +144,7 @@ public SoftLock lockRegion() throws CacheException { } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); @@ -152,7 +156,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version ); } @@ -163,7 +167,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public void remove(Object key) throws CacheException { + public void remove(NaturalIdCacheKey key) throws CacheException { try { actualStrategy.remove( key ); } @@ -183,7 +187,7 @@ public void removeAll() throws CacheException { } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { try { actualStrategy.unlockItem( key, lock ); } @@ -202,4 +206,9 @@ public void unlockRegion(SoftLock lock) throws CacheException { } } + @Override + public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } + } diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractEhcacheAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractEhcacheAccessStrategy.java index 63ed4faf2437..8ec4bda1a224 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractEhcacheAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractEhcacheAccessStrategy.java @@ -6,10 +6,21 @@ */ package org.hibernate.cache.ehcache.internal.strategy; +import java.io.Serializable; + import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheTransactionalDataRegion; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.CollectionCacheKey; +import org.hibernate.cache.spi.EntityCacheKey; +import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.SoftLock; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; /** * Ultimate superclass for all Ehcache specific Hibernate AccessStrategy implementations. @@ -19,7 +30,7 @@ * @author Chris Dennis * @author Alex Snaps */ -abstract class AbstractEhcacheAccessStrategy { +abstract class AbstractEhcacheAccessStrategy { private final T region; private final SessionFactoryOptions settings; @@ -55,7 +66,7 @@ protected SessionFactoryOptions settings() { * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object) */ - public final boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + public final boolean putFromLoad(K key, Object value, long txTimestamp, Object version) throws CacheException { return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() ); } @@ -66,7 +77,7 @@ public final boolean putFromLoad(Object key, Object value, long txTimestamp, Obj * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object, boolean) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object, boolean) */ - public abstract boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public abstract boolean putFromLoad(K key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException; /** @@ -99,7 +110,7 @@ public final void unlockRegion(SoftLock lock) throws CacheException { * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#remove(java.lang.Object) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#remove(java.lang.Object) */ - public void remove(Object key) throws CacheException { + public void remove(K key) throws CacheException { } /** @@ -120,7 +131,7 @@ public final void removeAll() throws CacheException { * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#evict(java.lang.Object) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#evict(java.lang.Object) */ - public final void evict(Object key) throws CacheException { + public final void evict(K key) throws CacheException { region.remove( key ); } @@ -134,4 +145,16 @@ public final void evict(Object key) throws CacheException { public final void evictAll() throws CacheException { region.clear(); } + + public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + + public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + + public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } } 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..81b6324676a8 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 @@ -15,8 +15,8 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.EhCacheMessageLogger; import org.hibernate.cache.ehcache.internal.regions.EhcacheTransactionalDataRegion; +import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.access.SoftLock; - import org.jboss.logging.Logger; /** @@ -27,9 +27,8 @@ * @author Chris Dennis * @author Alex Snaps */ -abstract class AbstractReadWriteEhcacheAccessStrategy - extends AbstractEhcacheAccessStrategy { +abstract class AbstractReadWriteEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy { private static final EhCacheMessageLogger LOG = Logger.getMessageLogger( EhCacheMessageLogger.class, @@ -56,7 +55,7 @@ public AbstractReadWriteEhcacheAccessStrategy(T region, SessionFactoryOptions se * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#get(java.lang.Object, long) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#get(java.lang.Object, long) */ - public final Object get(Object key, long txTimestamp) throws CacheException { + public final Object get(K key, long txTimestamp) throws CacheException { readLockIfNeeded( key ); try { final Lockable item = (Lockable) region().get( key ); @@ -83,7 +82,7 @@ public final Object get(Object key, long txTimestamp) throws CacheException { */ @Override public final boolean putFromLoad( - Object key, + K key, Object value, long txTimestamp, Object version, @@ -112,7 +111,7 @@ public final boolean putFromLoad( * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#lockItem(java.lang.Object, java.lang.Object) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#lockItem(java.lang.Object, java.lang.Object) */ - public final SoftLock lockItem(Object key, Object version) throws CacheException { + public final SoftLock lockItem(K key, Object version) throws CacheException { region().writeLock( key ); try { final Lockable item = (Lockable) region().get( key ); @@ -136,7 +135,7 @@ public final SoftLock lockItem(Object key, Object version) throws CacheException * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#unlockItem(java.lang.Object, org.hibernate.cache.spi.access.SoftLock) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#unlockItem(java.lang.Object, org.hibernate.cache.spi.access.SoftLock) */ - public final void unlockItem(Object key, SoftLock lock) throws CacheException { + public final void unlockItem(K key, SoftLock lock) throws CacheException { region().writeLock( key ); try { final Lockable item = (Lockable) region().get( key ); 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..be0854bbf11d 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,6 +9,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion; +import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -20,7 +21,7 @@ * @author Alex Snaps */ public class NonStrictReadWriteEhcacheCollectionRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements CollectionRegionAccessStrategy { /** @@ -39,12 +40,12 @@ public CollectionRegion getRegion() { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -61,7 +62,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheException { return null; } @@ -71,12 +72,12 @@ public SoftLock lockItem(Object key, Object version) throws CacheException { * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { region().remove( key ); } @Override - public void remove(Object key) throws CacheException { + public void remove(CollectionCacheKey key) throws CacheException { region().remove( key ); } } 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..e68abd03c3b5 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 @@ -6,12 +6,17 @@ */ package org.hibernate.cache.ehcache.internal.strategy; +import java.io.Serializable; + import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; +import org.hibernate.cache.spi.EntityCacheKey; 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 @@ -20,7 +25,7 @@ * @author Alex Snaps */ public class NonStrictReadWriteEhcacheEntityRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements EntityRegionAccessStrategy { /** @@ -39,12 +44,12 @@ public EntityRegion getRegion() { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -61,7 +66,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheException { return null; } @@ -71,7 +76,7 @@ public SoftLock lockItem(Object key, Object version) throws CacheException { * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { region().remove( key ); } @@ -81,7 +86,7 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { * Returns false since this is an asynchronous cache access strategy. */ @Override - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; } @@ -91,7 +96,7 @@ public boolean insert(Object key, Object value, Object version) throws CacheExce * Returns false since this is a non-strict read/write cache access strategy */ @Override - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; } @@ -101,21 +106,22 @@ public boolean afterInsert(Object key, Object value, Object version) throws Cach * Removes the entry since this is a non-strict read/write cache strategy. */ @Override - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { remove( key ); return false; } @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { unlockItem( key, lock ); return false; } @Override - public void remove(Object key) throws CacheException { + public void remove(EntityCacheKey key) throws CacheException { region().remove( key ); } + } 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..55370872530b 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.spi.NaturalIdCacheKey; 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 @@ -20,7 +23,7 @@ * @author Alex Snaps */ public class NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements NaturalIdRegionAccessStrategy { /** @@ -39,12 +42,12 @@ public NaturalIdRegion getRegion() { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -61,7 +64,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheException { return null; } @@ -71,7 +74,7 @@ public SoftLock lockItem(Object key, Object version) throws CacheException { * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { region().remove( key ); } @@ -81,7 +84,7 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { * Returns false since this is an asynchronous cache access strategy. */ @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @@ -91,7 +94,7 @@ public boolean insert(Object key, Object value) throws CacheException { * Returns false since this is a non-strict read/write cache access strategy */ @Override - public boolean afterInsert(Object key, Object value) throws CacheException { + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @@ -101,19 +104,20 @@ public boolean afterInsert(Object key, Object value) throws CacheException { * Removes the entry since this is a non-strict read/write cache strategy. */ @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { remove( key ); return false; } @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { unlockItem( key, lock ); return false; } @Override - public void remove(Object key) throws CacheException { + public void remove(NaturalIdCacheKey key) throws CacheException { region().remove( key ); } + } 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..0b048b24fdcf 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,6 +9,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion; +import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -20,7 +21,7 @@ * @author Alex Snaps */ public class ReadOnlyEhcacheCollectionRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements CollectionRegionAccessStrategy { /** @@ -39,12 +40,12 @@ public CollectionRegion getRegion() { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -56,7 +57,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public SoftLock lockItem(Object key, Object version) throws UnsupportedOperationException { + public SoftLock lockItem(CollectionCacheKey key, Object version) throws UnsupportedOperationException { return null; } @@ -66,6 +67,6 @@ public SoftLock lockItem(Object key, Object version) throws UnsupportedOperation * A no-op since this cache is read-only */ @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { } } 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..a09bbafb3012 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,6 +9,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -19,7 +20,7 @@ * @author Chris Dennis * @author Alex Snaps */ -public class ReadOnlyEhcacheEntityRegionAccessStrategy extends AbstractEhcacheAccessStrategy +public class ReadOnlyEhcacheEntityRegionAccessStrategy extends AbstractEhcacheAccessStrategy implements EntityRegionAccessStrategy { /** @@ -38,12 +39,12 @@ public EntityRegion getRegion() { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -55,7 +56,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public SoftLock lockItem(Object key, Object version) throws UnsupportedOperationException { + public SoftLock lockItem(EntityCacheKey key, Object version) throws UnsupportedOperationException { return null; } @@ -65,7 +66,7 @@ public SoftLock lockItem(Object key, Object version) throws UnsupportedOperation * A no-op since this cache is read-only */ @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { evict( key ); } @@ -75,12 +76,12 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { * This cache is asynchronous hence a no-op */ @Override - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; } @Override - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { region().put( key, value ); return true; } @@ -93,7 +94,7 @@ public boolean afterInsert(Object key, Object value, Object version) throws Cach * @throws UnsupportedOperationException always */ @Override - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws UnsupportedOperationException { throw new UnsupportedOperationException( "Can't write to a readonly object" ); } @@ -106,7 +107,7 @@ public boolean update(Object key, Object value, Object currentVersion, Object pr * @throws UnsupportedOperationException always */ @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws UnsupportedOperationException { throw new UnsupportedOperationException( "Can't write to a readonly object" ); } 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..0a0e26cfff90 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,6 +9,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion; +import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -20,7 +21,7 @@ * @author Alex Snaps */ public class ReadOnlyEhcacheNaturalIdRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements NaturalIdRegionAccessStrategy { /** @@ -39,12 +40,12 @@ public NaturalIdRegion getRegion() { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -56,7 +57,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } @Override - public SoftLock lockItem(Object key, Object version) throws UnsupportedOperationException { + public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws UnsupportedOperationException { return null; } @@ -66,7 +67,7 @@ public SoftLock lockItem(Object key, Object version) throws UnsupportedOperation * A no-op since this cache is read-only */ @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { region().remove( key ); } @@ -76,12 +77,12 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { * This cache is asynchronous hence a no-op */ @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @Override - public boolean afterInsert(Object key, Object value) throws CacheException { + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { region().put( key, value ); return true; } @@ -94,7 +95,7 @@ public boolean afterInsert(Object key, Object value) throws CacheException { * @throws UnsupportedOperationException always */ @Override - public boolean update(Object key, Object value) throws UnsupportedOperationException { + public boolean update(NaturalIdCacheKey key, Object value) throws UnsupportedOperationException { throw new UnsupportedOperationException( "Can't write to a readonly object" ); } @@ -106,7 +107,7 @@ public boolean update(Object key, Object value) throws UnsupportedOperationExcep * @throws UnsupportedOperationException always */ @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws UnsupportedOperationException { + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws UnsupportedOperationException { throw new UnsupportedOperationException( "Can't write to a readonly object" ); } } 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..acd70b501899 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,6 +8,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion; +import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; @@ -18,7 +19,7 @@ * @author Alex Snaps */ public class ReadWriteEhcacheCollectionRegionAccessStrategy - extends AbstractReadWriteEhcacheAccessStrategy + extends AbstractReadWriteEhcacheAccessStrategy implements CollectionRegionAccessStrategy { /** 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..7b0a088ba8b8 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,6 +9,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -20,7 +21,7 @@ * @author Alex Snaps */ public class ReadWriteEhcacheEntityRegionAccessStrategy - extends AbstractReadWriteEhcacheAccessStrategy + extends AbstractReadWriteEhcacheAccessStrategy implements EntityRegionAccessStrategy { /** @@ -44,7 +45,7 @@ public EntityRegion getRegion() { * A no-op since this is an asynchronous cache access strategy. */ @Override - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; } @@ -54,7 +55,7 @@ public boolean insert(Object key, Object value, Object version) throws CacheExce * Inserts will only succeed if there is no existing value mapped to this key. */ @Override - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { region().writeLock( key ); try { final Lockable item = (Lockable) region().get( key ); @@ -77,7 +78,7 @@ public boolean afterInsert(Object key, Object value, Object version) throws Cach * A no-op since this is an asynchronous cache access strategy. */ @Override - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return false; } @@ -90,7 +91,7 @@ public boolean update(Object key, Object value, Object currentVersion, Object pr * the course of this transaction. */ @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { //what should we do with previousVersion here? region().writeLock( key ); 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..86629de1da4f 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,6 +9,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion; +import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -20,7 +21,7 @@ * @author Alex Snaps */ public class ReadWriteEhcacheNaturalIdRegionAccessStrategy - extends AbstractReadWriteEhcacheAccessStrategy + extends AbstractReadWriteEhcacheAccessStrategy implements NaturalIdRegionAccessStrategy { /** @@ -44,7 +45,7 @@ public NaturalIdRegion getRegion() { * A no-op since this is an asynchronous cache access strategy. */ @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @@ -54,7 +55,7 @@ public boolean insert(Object key, Object value) throws CacheException { * Inserts will only succeed if there is no existing value mapped to this key. */ @Override - public boolean afterInsert(Object key, Object value) throws CacheException { + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { region().writeLock( key ); try { final Lockable item = (Lockable) region().get( key ); @@ -77,7 +78,7 @@ public boolean afterInsert(Object key, Object value) throws CacheException { * A no-op since this is an asynchronous cache access strategy. */ @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @@ -89,7 +90,7 @@ public boolean update(Object key, Object value) throws CacheException { * the course of this transaction. */ @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { //what should we do with previousVersion here? region().writeLock( key ); try { 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..fa474b770d86 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 @@ -6,15 +6,20 @@ */ package org.hibernate.cache.ehcache.internal.strategy; +import java.io.Serializable; + 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.spi.CollectionCacheKey; 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. @@ -24,7 +29,7 @@ * @author Alex Snaps */ public class TransactionalEhcacheCollectionRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements CollectionRegionAccessStrategy { private final Ehcache ehcache; @@ -45,7 +50,7 @@ public TransactionalEhcacheCollectionRegionAccessStrategy( } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { try { final Element element = ehcache.get( key ); return element == null ? null : element.getObjectValue(); @@ -61,13 +66,13 @@ public CollectionRegion getRegion() { } @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheException { return null; } @Override public boolean putFromLoad( - Object key, + CollectionCacheKey key, Object value, long txTimestamp, Object version, @@ -86,7 +91,7 @@ public boolean putFromLoad( } @Override - public void remove(Object key) throws CacheException { + public void remove(CollectionCacheKey key) throws CacheException { try { ehcache.remove( key ); } @@ -96,7 +101,7 @@ public void remove(Object key) throws CacheException { } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { // no-op } 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..9f38d620c8d2 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 @@ -12,6 +12,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -23,7 +24,7 @@ * @author Ludovic Orban * @author Alex Snaps */ -public class TransactionalEhcacheEntityRegionAccessStrategy extends AbstractEhcacheAccessStrategy +public class TransactionalEhcacheEntityRegionAccessStrategy extends AbstractEhcacheAccessStrategy implements EntityRegionAccessStrategy { private final Ehcache ehcache; @@ -44,17 +45,17 @@ public TransactionalEhcacheEntityRegionAccessStrategy( } @Override - public boolean afterInsert(Object key, Object value, Object version) { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) { return false; } @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { return false; } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { try { final Element element = ehcache.get( key ); return element == null ? null : element.getObjectValue(); @@ -70,7 +71,7 @@ public EntityRegion getRegion() { } @Override - public boolean insert(Object key, Object value, Object version) + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { //OptimisticCache? versioning? try { @@ -83,13 +84,13 @@ public boolean insert(Object key, Object value, Object version) } @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheException { return null; } @Override public boolean putFromLoad( - Object key, + EntityCacheKey key, Object value, long txTimestamp, Object version, @@ -108,7 +109,7 @@ public boolean putFromLoad( } @Override - public void remove(Object key) throws CacheException { + public void remove(EntityCacheKey key) throws CacheException { try { ehcache.remove( key ); } @@ -118,13 +119,13 @@ public void remove(Object key) throws CacheException { } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { // no-op } @Override public boolean update( - Object key, + EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { 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..64b1606fed8d 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 @@ -12,6 +12,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion; +import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -24,7 +25,7 @@ * @author Alex Snaps */ public class TransactionalEhcacheNaturalIdRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements NaturalIdRegionAccessStrategy { private final Ehcache ehcache; @@ -45,17 +46,17 @@ public TransactionalEhcacheNaturalIdRegionAccessStrategy( } @Override - public boolean afterInsert(Object key, Object value) { + public boolean afterInsert(NaturalIdCacheKey key, Object value) { return false; } @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) { + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) { return false; } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { try { final Element element = ehcache.get( key ); return element == null ? null : element.getObjectValue(); @@ -71,7 +72,7 @@ public NaturalIdRegion getRegion() { } @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { //OptimisticCache? versioning? try { ehcache.put( new Element( key, value ) ); @@ -83,13 +84,13 @@ public boolean insert(Object key, Object value) throws CacheException { } @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheException { return null; } @Override public boolean putFromLoad( - Object key, + NaturalIdCacheKey key, Object value, long txTimestamp, Object version, @@ -108,7 +109,7 @@ public boolean putFromLoad( } @Override - public void remove(Object key) throws CacheException { + public void remove(NaturalIdCacheKey key) throws CacheException { try { ehcache.remove( key ); } @@ -118,12 +119,12 @@ public void remove(Object key) throws CacheException { } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { // no-op } @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { try { ehcache.put( new Element( key, value ) ); return true; 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..7f928e859ed6 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 @@ -6,11 +6,17 @@ */ package org.hibernate.cache.infinispan.collection; +import java.io.Serializable; + import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.CollectionCacheKey; 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. @@ -30,7 +36,7 @@ class TransactionalAccess implements CollectionRegionAccessStrategy { this.delegate = new TransactionalAccessDelegate( region, region.getPutFromLoadValidator() ); } - public void evict(Object key) throws CacheException { + public void evict(CollectionCacheKey key) throws CacheException { delegate.evict( key ); } @@ -38,20 +44,20 @@ public void evictAll() throws CacheException { delegate.evictAll(); } - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { return delegate.get( key, txTimestamp ); } - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version ); } - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); } - public void remove(Object key) throws CacheException { + public void remove(CollectionCacheKey key) throws CacheException { delegate.remove( key ); } @@ -63,7 +69,7 @@ public CollectionRegion getRegion() { return region; } - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheException { return null; } @@ -71,10 +77,15 @@ public SoftLock lockRegion() throws CacheException { return null; } - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { } public void unlockRegion(SoftLock lock) throws CacheException { } + @Override + public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java index 38da0a84b5ed..a034899fcb91 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java @@ -7,6 +7,7 @@ package org.hibernate.cache.infinispan.entity; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -25,14 +26,14 @@ class ReadOnlyAccess extends TransactionalAccess { @Override public boolean update( - Object key, Object value, Object currentVersion, + EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); } @Override public boolean afterUpdate( - Object key, Object value, Object currentVersion, + EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, 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/entity/TransactionalAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java index c9f997fe0e06..2d5bf8319306 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 @@ -6,11 +6,17 @@ */ package org.hibernate.cache.infinispan.entity; +import java.io.Serializable; + import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.EntityCacheKey; 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. @@ -30,7 +36,7 @@ class TransactionalAccess implements EntityRegionAccessStrategy { this.delegate = new TransactionalAccessDelegate( region, region.getPutFromLoadValidator() ); } - public void evict(Object key) throws CacheException { + public void evict(EntityCacheKey key) throws CacheException { delegate.evict( key ); } @@ -38,7 +44,7 @@ public void evictAll() throws CacheException { delegate.evictAll(); } - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { return delegate.get( key, txTimestamp ); } @@ -46,20 +52,20 @@ public EntityRegion getRegion() { return this.region; } - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { return delegate.insert( key, value, version ); } - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version ); } - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); } - public void remove(Object key) throws CacheException { + public void remove(EntityCacheKey key) throws CacheException { delegate.remove( key ); } @@ -67,12 +73,12 @@ public void removeAll() throws CacheException { delegate.removeAll(); } - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return delegate.update( key, value, currentVersion, previousVersion ); } - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheException { return null; } @@ -80,18 +86,24 @@ public SoftLock lockRegion() throws CacheException { return null; } - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { } public void unlockRegion(SoftLock lock) throws CacheException { } - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; } - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { return false; } + + @Override + public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + } 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..bef04363d164 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 @@ -7,6 +7,7 @@ package org.hibernate.cache.infinispan.naturalid; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -18,14 +19,14 @@ class ReadOnlyAccess extends TransactionalAccess { super( naturalIdRegion ); } - @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); } @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(NaturalIdCacheKey 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..bd0ba14fbfc5 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,13 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.NaturalIdCacheKey; 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 @@ -25,12 +29,12 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy { } @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { return delegate.insert( key, value, null ); } @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { return delegate.update( key, value, null, null ); } @@ -40,7 +44,7 @@ public NaturalIdRegion getRegion() { } @Override - public void evict(Object key) throws CacheException { + public void evict(NaturalIdCacheKey key) throws CacheException { delegate.evict( key ); } @@ -50,23 +54,23 @@ public void evictAll() throws CacheException { } @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { return delegate.get( key, txTimestamp ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); } @Override - public void remove(Object key) throws CacheException { + public void remove(NaturalIdCacheKey key) throws CacheException { delegate.remove( key ); } @@ -76,7 +80,7 @@ public void removeAll() throws CacheException { } @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheException { return null; } @@ -86,7 +90,7 @@ public SoftLock lockRegion() throws CacheException { } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { } @Override @@ -94,13 +98,18 @@ public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public boolean afterInsert(Object key, Object value) throws CacheException { + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { return false; } + @Override + public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } + } 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..fd48bbb4e1cd 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 @@ -12,10 +12,10 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKey; 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; @@ -29,7 +29,7 @@ * @author Galder Zamarreño * @since 3.5 */ -public abstract class AbstractEntityCollectionRegionTestCase extends AbstractRegionImplTestCase { +public abstract class AbstractEntityCollectionRegionTestCase extends AbstractRegionImplTestCase { @Test public void testSupportedAccessTypes() throws Exception { supportedAccessTypeTest(); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java index 09ba0db2a9f5..e41e243e93de 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 @@ -12,17 +12,15 @@ import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; +import org.hibernate.cache.spi.CacheKey; 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 static org.junit.Assert.assertEquals; @@ -34,7 +32,7 @@ * @author Galder Zamarreño * @since 3.5 */ -public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionImplTestCase { +public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionImplTestCase { private static final Logger log = Logger.getLogger( AbstractGeneralDataRegionTestCase.class ); protected static final String KEY = "Key"; @@ -52,12 +50,12 @@ protected StandardServiceRegistryBuilder createStandardServiceRegistryBuilder() } @Override - protected void putInRegion(Region region, Object key, Object value) { + protected void putInRegion(Region region, T key, Object value) { ((GeneralDataRegion) region).put( key, value ); } @Override - protected void removeFromRegion(Region region, Object key) { + protected void removeFromRegion(Region region, T key) { ((GeneralDataRegion) region).evict( key ); } diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java index 2daf5ad2e0d9..23c59bf62ecb 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java @@ -11,6 +11,7 @@ import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.Region; import org.hibernate.internal.util.compare.ComparableComparator; import org.infinispan.AdvancedCache; @@ -21,15 +22,15 @@ * @author Galder Zamarreño * @since 3.5 */ -public abstract class AbstractRegionImplTestCase extends AbstractNonFunctionalTestCase { +public abstract class AbstractRegionImplTestCase extends AbstractNonFunctionalTestCase { protected abstract AdvancedCache getInfinispanCache(InfinispanRegionFactory regionFactory); protected abstract Region createRegion(InfinispanRegionFactory regionFactory, String regionName, Properties properties, CacheDataDescription cdd); - protected abstract void putInRegion(Region region, Object key, Object value); + protected abstract void putInRegion(Region region, T key, Object value); - protected abstract void removeFromRegion(Region region, Object key); + protected abstract void removeFromRegion(Region region, T key); protected CacheDataDescription getCacheDataDescription() { return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE); 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..efa2eb66d09d 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 @@ -12,6 +12,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; + import javax.transaction.TransactionManager; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; @@ -22,22 +23,23 @@ import org.hibernate.cache.infinispan.util.Caches; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CollectionCacheKey; 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.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; + import junit.framework.AssertionFailedError; import org.infinispan.test.CacheManagerCallable; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.transaction.tm.BatchModeTransactionManager; - import org.jboss.logging.Logger; import static org.infinispan.test.TestingUtil.withCacheManager; @@ -230,7 +232,7 @@ public void testPutFromLoadMinimal() throws Exception { private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { - final String KEY = KEY_BASE + testCount++; + final CollectionCacheKey KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ ); final CountDownLatch writeLatch1 = new CountDownLatch( 1 ); final CountDownLatch writeLatch2 = new CountDownLatch( 1 ); @@ -382,7 +384,7 @@ public void testEvictAll() throws Exception { private void evictOrRemoveTest(final boolean evict) throws Exception { - final String KEY = KEY_BASE + testCount++; + final CollectionCacheKey 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 +415,7 @@ public Void call() throws Exception { private void evictOrRemoveAllTest(final boolean evict) throws Exception { - final String KEY = KEY_BASE + testCount++; + final CollectionCacheKey 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..88373f3f65f9 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java @@ -10,6 +10,7 @@ import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.RegionFactory; @@ -28,7 +29,8 @@ * * @author Galder Zamarreño */ -public class CollectionRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { +public class CollectionRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { + private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); @Override @@ -60,13 +62,13 @@ protected AdvancedCache getInfinispanCache(InfinispanRegionFactory regionFactory } @Override - protected void putInRegion(Region region, Object key, Object value) { + protected void putInRegion(Region region, CollectionCacheKey key, Object value) { CollectionRegionAccessStrategy strategy = ((CollectionRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL); strategy.putFromLoad(key, value, System.currentTimeMillis(), new Integer(1)); } @Override - protected void removeFromRegion(Region region, Object key) { + protected void removeFromRegion(Region region, CollectionCacheKey key) { ((CollectionRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).remove(key); } 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..b8b63c473fc6 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java @@ -8,13 +8,14 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; +import org.hibernate.cache.spi.CollectionCacheKey; 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 +31,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 CollectionCacheKey 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..90e0a8178272 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 @@ -17,22 +17,23 @@ import org.hibernate.cache.infinispan.util.Caches; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.EntityCacheKey; 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.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; + import junit.framework.AssertionFailedError; import org.infinispan.Cache; import org.infinispan.test.TestingUtil; import org.infinispan.transaction.tm.BatchModeTransactionManager; - import org.jboss.logging.Logger; import static org.junit.Assert.assertEquals; @@ -193,7 +194,7 @@ public void testPutFromLoadMinimal() throws Exception { */ private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { - final String KEY = KEY_BASE + testCount++; + final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final CountDownLatch writeLatch1 = new CountDownLatch(1); final CountDownLatch writeLatch2 = new CountDownLatch(1); @@ -297,7 +298,7 @@ public void run() { @Test public void testInsert() throws Exception { - final String KEY = KEY_BASE + testCount++; + final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final CountDownLatch readLatch = new CountDownLatch(1); final CountDownLatch commitLatch = new CountDownLatch(1); @@ -386,7 +387,7 @@ public void run() { @Test public void testUpdate() throws Exception { - final String KEY = KEY_BASE + testCount++; + final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); // Set up initial state localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); @@ -502,7 +503,7 @@ public void testEvictAll() throws Exception { } private void evictOrRemoveTest(final boolean evict) throws Exception { - final String KEY = KEY_BASE + testCount++; + final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); assertEquals(0, getValidKeyCount(localEntityRegion.getCache().keySet())); assertEquals(0, getValidKeyCount(remoteEntityRegion.getCache().keySet())); @@ -531,7 +532,7 @@ public Void call() throws Exception { } private void evictOrRemoveAllTest(final boolean evict) throws Exception { - final String KEY = KEY_BASE + testCount++; + final EntityCacheKey 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..d6dd77ff13b1 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 @@ -6,10 +6,10 @@ */ package org.hibernate.test.cache.infinispan.entity; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.AccessType; - +import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; import org.junit.Test; - import org.infinispan.transaction.tm.BatchModeTransactionManager; import static org.junit.Assert.assertEquals; @@ -42,7 +42,7 @@ public void testPutFromLoadMinimal() throws Exception { private void putFromLoadTest(boolean minimal) throws Exception { - final String KEY = KEY_BASE + testCount++; + final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); @@ -64,8 +64,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 EntityCacheKey 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..87e549a18d2e 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,10 +10,12 @@ import java.util.concurrent.TimeUnit; import junit.framework.AssertionFailedError; + import org.infinispan.transaction.tm.BatchModeTransactionManager; import org.jboss.logging.Logger; - +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.AccessType; +import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -34,7 +36,7 @@ protected AccessType getAccessType() { public void testContestedPutFromLoad() throws Exception { - final String KEY = KEY_BASE + testCount++; + final EntityCacheKey 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..0ba2b2310e8b 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java @@ -10,6 +10,7 @@ import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.RegionFactory; @@ -28,7 +29,8 @@ * @author Galder Zamarreño * @since 3.5 */ -public class EntityRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { +public class EntityRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { + private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); @Override @@ -50,12 +52,12 @@ protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties p } @Override - protected void putInRegion(Region region, Object key, Object value) { + protected void putInRegion(Region region, EntityCacheKey key, Object value) { ((EntityRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).insert(key, value, 1); } @Override - protected void removeFromRegion(Region region, Object key) { + protected void removeFromRegion(Region region, EntityCacheKey key) { ((EntityRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).remove(key); } 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..cb86be8a48af 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 @@ -9,13 +9,14 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.infinispan.InfinispanRegionFactory; +import org.hibernate.cache.spi.EntityCacheKey; 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 +36,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 EntityCacheKey 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..f6e6ef39da7b 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 @@ -9,6 +9,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; + import javax.transaction.TransactionManager; import org.infinispan.Cache; @@ -20,10 +21,9 @@ import org.infinispan.util.logging.LogFactory; 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.cache.spi.EntityCacheKey; import org.hibernate.test.cache.infinispan.functional.Contact; import org.hibernate.test.cache.infinispan.functional.Customer; @@ -345,9 +345,9 @@ public boolean isEmpty() { public void nodeVisited(CacheEntryVisitedEvent event) { log.debug( event.toString() ); if ( !event.isPre() ) { - CacheKey cacheKey = (CacheKey) event.getKey(); + EntityCacheKey cacheKey = (EntityCacheKey) event.getKey(); Integer primKey = (Integer) cacheKey.getKey(); - String key = cacheKey.getEntityOrRoleName() + '#' + primKey; + String key = cacheKey.getEntityName() + '#' + primKey; 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/util/TestingKeyFactory.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/TestingKeyFactory.java new file mode 100644 index 000000000000..61b3dbe14fcc --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/util/TestingKeyFactory.java @@ -0,0 +1,84 @@ +/* + * 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; + +import org.hibernate.cache.spi.CollectionCacheKey; +import org.hibernate.cache.spi.EntityCacheKey; + +public class TestingKeyFactory { + + private TestingKeyFactory() { + //Not to be constructed + } + + public static EntityCacheKey generateEntityCacheKey(String id) { + return new TestingEntityCacheKey( id ); + } + + public static CollectionCacheKey generateCollectionCacheKey(String id) { + return new TestingEntityCacheKey( id ); + } + + //For convenience implement both interfaces. + private static class TestingEntityCacheKey implements EntityCacheKey, CollectionCacheKey, Serializable { + + private final String id; + + public TestingEntityCacheKey(String id) { + this.id = id; + } + + @Override + public Serializable getKey() { + return null; + } + + @Override + public String getEntityName() { + return null; + } + + @Override + public String getCollectionRole() { + return null; + } + + @Override + public String getTenantId() { + return null; + } + + @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/AbstractReadWriteAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java index ec2c2713cf26..e62c826ad4ae 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java @@ -13,6 +13,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.access.SoftLock; import org.jboss.logging.Logger; @@ -20,7 +21,7 @@ /** * @author Strong Liu */ -abstract class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy { +abstract class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy { private static final Logger LOG = Logger.getLogger( AbstractReadWriteAccessStrategy.class.getName() ); private final UUID uuid = UUID.randomUUID(); @@ -34,7 +35,7 @@ abstract class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy * after the start of this transaction. */ @Override - public final Object get(Object key, long txTimestamp) throws CacheException { + public final Object get(T key, long txTimestamp) throws CacheException { LOG.debugf( "getting key[%s] from region[%s]", key, getInternalRegion().getName() ); try { readLock.lock(); @@ -68,7 +69,7 @@ public final Object get(Object key, long txTimestamp) throws CacheException { */ @Override public final boolean putFromLoad( - Object key, + T key, Object value, long txTimestamp, Object version, @@ -108,7 +109,7 @@ public final boolean putFromLoad( * Soft-lock a cache item. */ @Override - public final SoftLock lockItem(Object key, Object version) throws CacheException { + public final SoftLock lockItem(T key, Object version) throws CacheException { try { LOG.debugf( "locking key[%s] in region[%s]", key, getInternalRegion().getName() ); @@ -132,7 +133,7 @@ public final SoftLock lockItem(Object key, Object version) throws CacheException * Soft-unlock a cache item. */ @Override - public final void unlockItem(Object key, SoftLock lock) throws CacheException { + public final void unlockItem(T key, SoftLock lock) throws CacheException { try { LOG.debugf( "unlocking key[%s] in region[%s]", key, getInternalRegion().getName() ); 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..20884b070371 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,20 @@ */ package org.hibernate.testing.cache; +import java.io.Serializable; + +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.CollectionCacheKey; 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 { +class BaseCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy { + private final CollectionRegionImpl region; BaseCollectionRegionAccessStrategy(CollectionRegionImpl region) { @@ -33,4 +40,10 @@ protected boolean isDefaultMinimalPutOverride() { public CollectionRegion getRegion() { return region; } + + @Override + public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + } 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..75849b7deaa1 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 @@ -6,45 +6,51 @@ */ package org.hibernate.testing.cache; +import java.io.Serializable; + import org.hibernate.cache.CacheException; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.EntityCacheKey; 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 { +class BaseEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy { + private final EntityRegionImpl region; BaseEntityRegionAccessStrategy(EntityRegionImpl region) { this.region = region; } - @Override public EntityRegion getRegion() { return region; } @Override - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { return putFromLoad( key, value, 0, version ); } @Override - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { return true; } @Override - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return false; } @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { return false; } @@ -58,4 +64,10 @@ protected BaseGeneralDataRegion getInternalRegion() { protected boolean isDefaultMinimalPutOverride() { return region.getSettings().isMinimalPutsEnabled(); } + + @Override + public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + } 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..e360085b8f4d 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 @@ -6,15 +6,23 @@ */ package org.hibernate.testing.cache; +import java.io.Serializable; + import org.hibernate.cache.CacheException; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.NaturalIdCacheKey; 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.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.Type; /** * @author Eric Dalquist */ -class BaseNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy { +class BaseNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy { private final NaturalIdRegionImpl region; @Override @@ -33,26 +41,31 @@ public NaturalIdRegion getRegion() { } @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { return putFromLoad( key, value, 0, null ); } @Override - public boolean afterInsert(Object key, Object value) throws CacheException { + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { return putFromLoad( key, value, 0, null ); } @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { return false; } BaseNaturalIdRegionAccessStrategy(NaturalIdRegionImpl region) { this.region = region; } + + @Override + public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } } 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..a8b6ab707bc9 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 @@ -7,34 +7,34 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.CacheKey; 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 ); +abstract class BaseRegionAccessStrategy implements RegionAccessStrategy { + private static final Logger LOG = Logger.getLogger( BaseRegionAccessStrategy.class ); protected abstract BaseGeneralDataRegion getInternalRegion(); protected abstract boolean isDefaultMinimalPutOverride(); @Override - public Object get(Object key, long txTimestamp) throws CacheException { + public Object get(T key, long txTimestamp) throws CacheException { return getInternalRegion().get( key ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(T key, Object value, long txTimestamp, Object version) throws CacheException { return putFromLoad( key, value, txTimestamp, version, isDefaultMinimalPutOverride() ); } @Override - public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(T key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( key == null || value == null ) { @@ -75,12 +75,12 @@ public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public SoftLock lockItem(Object key, Object version) throws CacheException { + public SoftLock lockItem(T key, Object version) throws CacheException { return null; } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(T key, SoftLock lock) throws CacheException { } @@ -91,7 +91,7 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#remove(java.lang.Object) */ @Override - public void remove(Object key) throws CacheException { + public void remove(T key) throws CacheException { } /** @@ -107,7 +107,7 @@ public void removeAll() throws CacheException { } @Override - public void evict(Object key) throws CacheException { + public void evict(T key) throws CacheException { getInternalRegion().evict( key ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteCollectionRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteCollectionRegionAccessStrategy.java index 4b261979a1bf..58a288ca29c9 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteCollectionRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteCollectionRegionAccessStrategy.java @@ -7,6 +7,7 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -18,12 +19,12 @@ class NonstrictReadWriteCollectionRegionAccessStrategy extends BaseCollectionReg } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { evict( key ); } @Override - public void remove(Object key) throws CacheException { + public void remove(CollectionCacheKey key) throws CacheException { evict( key ); } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteEntityRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteEntityRegionAccessStrategy.java index 70c9c8623d2f..6435c9356f90 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteEntityRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteEntityRegionAccessStrategy.java @@ -7,6 +7,7 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -21,7 +22,7 @@ class NonstrictReadWriteEntityRegionAccessStrategy extends BaseEntityRegionAcces * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { evict( key ); } @@ -29,7 +30,7 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { * Returns false since this is an asynchronous cache access strategy. */ @Override - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; } @@ -37,7 +38,7 @@ public boolean insert(Object key, Object value, Object version) throws CacheExce * Returns false since this is a non-strict read/write cache access strategy */ @Override - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; } @@ -45,21 +46,21 @@ public boolean afterInsert(Object key, Object value, Object version) throws Cach * Removes the entry since this is a non-strict read/write cache strategy. */ @Override - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { evict( key ); return false; } @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { unlockItem( key, lock ); return false; } @Override - public void remove(Object key) throws CacheException { + public void remove(EntityCacheKey key) throws CacheException { evict( key ); } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteNaturalIdRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteNaturalIdRegionAccessStrategy.java index 3f23270588d1..830d37269e5e 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteNaturalIdRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteNaturalIdRegionAccessStrategy.java @@ -7,6 +7,7 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -18,27 +19,27 @@ class NonstrictReadWriteNaturalIdRegionAccessStrategy extends BaseNaturalIdRegio } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { evict( key ); } @Override - public void remove(Object key) throws CacheException { + public void remove(NaturalIdCacheKey key) throws CacheException { evict( key ); } @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @Override - public boolean afterInsert(Object key, Object value) throws CacheException { + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { remove( key ); return false; } 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..a3aa01ba1f94 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 @@ -7,8 +7,8 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.SoftLock; - import org.jboss.logging.Logger; /** @@ -26,18 +26,18 @@ class ReadOnlyEntityRegionAccessStrategy extends BaseEntityRegionAccessStrategy * This cache is asynchronous hence a no-op */ @Override - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; //wait until tx complete, see afterInsert(). } @Override - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { getInternalRegion().put( key, value ); //save into cache since the tx is completed return true; } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { evict( key ); } @@ -47,7 +47,7 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException { * @throws UnsupportedOperationException always */ @Override - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { LOG.info( "Illegal attempt to update item cached as read-only : " + key ); throw new UnsupportedOperationException( "Can't write to a readonly object" ); @@ -59,7 +59,7 @@ public boolean update(Object key, Object value, Object currentVersion, Object pr * @throws UnsupportedOperationException always */ @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { LOG.info( "Illegal attempt to update item cached as read-only : " + key ); throw new UnsupportedOperationException( "Can't write to a readonly object" ); diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyNaturalIdRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyNaturalIdRegionAccessStrategy.java index 93f3b9b7ec9a..3b3a064c171c 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyNaturalIdRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyNaturalIdRegionAccessStrategy.java @@ -7,6 +7,7 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -18,7 +19,7 @@ class ReadOnlyNaturalIdRegionAccessStrategy extends BaseNaturalIdRegionAccessStr } @Override - public void unlockItem(Object key, SoftLock lock) throws CacheException { + public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { evict( key ); } } 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..ed4389f84d31 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 @@ -6,15 +6,20 @@ */ package org.hibernate.testing.cache; +import java.io.Serializable; import java.util.Comparator; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.CollectionCacheKey; 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 ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy +class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements CollectionRegionAccessStrategy { private final CollectionRegionImpl region; @@ -42,4 +47,10 @@ protected boolean isDefaultMinimalPutOverride() { public CollectionRegion getRegion() { return region; } + + @Override + public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + } + } 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..382f98dbb9d7 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 @@ -6,17 +6,22 @@ */ package org.hibernate.testing.cache; +import java.io.Serializable; import java.util.Comparator; import org.hibernate.cache.CacheException; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.EntityCacheKey; 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 ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrategy +class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements EntityRegionAccessStrategy { private final EntityRegionImpl region; @@ -25,18 +30,18 @@ class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrateg } @Override - public boolean insert(Object key, Object value, Object version) throws CacheException { + public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { return false; } @Override - public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return false; } @Override - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { try { writeLock.lock(); @@ -56,7 +61,7 @@ public boolean afterInsert(Object key, Object value, Object version) throws Cach @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { try { writeLock.lock(); @@ -103,4 +108,10 @@ Comparator getVersionComparator() { public EntityRegion getRegion() { return region; } + + @Override + public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + } + } 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..2cb429c6d68e 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,14 +9,18 @@ import java.util.Comparator; import org.hibernate.cache.CacheException; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.spi.NaturalIdCacheKey; 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 */ -class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStrategy +class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements NaturalIdRegionAccessStrategy { private final NaturalIdRegionImpl region; @@ -26,17 +30,17 @@ class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStra } @Override - public boolean insert(Object key, Object value) throws CacheException { + public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @Override - public boolean update(Object key, Object value) throws CacheException { + public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { return false; } @Override - public boolean afterInsert(Object key, Object value) throws CacheException { + public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { try { writeLock.lock(); @@ -56,7 +60,7 @@ public boolean afterInsert(Object key, Object value) throws CacheException { @Override - public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { try { writeLock.lock(); Lockable item = (Lockable) region.get( key ); @@ -101,4 +105,9 @@ protected boolean isDefaultMinimalPutOverride() { public NaturalIdRegion getRegion() { return region; } + + @Override + public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalCollectionRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalCollectionRegionAccessStrategy.java index f789f70fea96..35c510cb8146 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalCollectionRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalCollectionRegionAccessStrategy.java @@ -7,6 +7,7 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.CollectionCacheKey; /** * @author Strong Liu @@ -17,7 +18,7 @@ class TransactionalCollectionRegionAccessStrategy extends BaseCollectionRegionAc } @Override - public void remove(Object key) throws CacheException { + public void remove(CollectionCacheKey key) throws CacheException { evict( key ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalEntityRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalEntityRegionAccessStrategy.java index 56507eaf001a..502b2745de25 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalEntityRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalEntityRegionAccessStrategy.java @@ -7,6 +7,7 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -18,23 +19,23 @@ class TransactionalEntityRegionAccessStrategy extends BaseEntityRegionAccessStra } @Override - public boolean afterInsert(Object key, Object value, Object version) { + public boolean afterInsert(EntityCacheKey key, Object value, Object version) { return false; } @Override - public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { + public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { return false; } @Override - public void remove(Object key) throws CacheException { + public void remove(EntityCacheKey key) throws CacheException { evict( key ); } @Override public boolean update( - Object key, Object value, Object currentVersion, + EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return insert( key, value, currentVersion ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalNaturalIdRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalNaturalIdRegionAccessStrategy.java index 23e644457856..3ddfa1fa66e6 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalNaturalIdRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalNaturalIdRegionAccessStrategy.java @@ -7,6 +7,7 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; +import org.hibernate.cache.spi.NaturalIdCacheKey; /** * @author Eric Dalquist @@ -17,7 +18,7 @@ class TransactionalNaturalIdRegionAccessStrategy extends BaseNaturalIdRegionAcce } @Override - public void remove(Object key) throws CacheException { + public void remove(NaturalIdCacheKey key) throws CacheException { evict( key ); } From 7a3eb9ff78effb59b01fb62708648f98e43f1208 Mon Sep 17 00:00:00 2001 From: Radim Vansa Date: Mon, 8 Jun 2015 14:23:16 +0200 Subject: [PATCH 3/7] HHH-9840 - to be squashed * Replaced all CacheKey with Object * Because of statistics, added unwrap operation to all AccessStrategies ** This is to be reviewed yet, since I had to modify SessionFactoryImplementor interface --- .../action/internal/CollectionAction.java | 7 ++-- .../action/internal/EntityDeleteAction.java | 5 +-- .../action/internal/EntityInsertAction.java | 9 ++--- .../action/internal/EntityUpdateAction.java | 9 ++--- .../internal/CollectionCacheInvalidator.java | 3 +- .../internal/DefaultCacheKeysFactory.java | 22 +++++++---- .../internal/OldCacheKeyImplementation.java | 38 +++++-------------- .../cache/internal/OldNaturalIdCacheKey.java | 3 +- .../org/hibernate/cache/spi/CacheKey.java | 18 --------- .../cache/spi/CollectionCacheKey.java | 26 ------------- .../hibernate/cache/spi/EntityCacheKey.java | 26 ------------- .../cache/spi/NaturalIdCacheKey.java | 23 ----------- .../CollectionRegionAccessStrategy.java | 15 +++++--- .../access/EntityRegionAccessStrategy.java | 23 ++++++----- .../access/NaturalIdRegionAccessStrategy.java | 21 ++++++---- .../spi/access/RegionAccessStrategy.java | 17 ++++----- .../engine/internal/CacheHelper.java | 7 ++-- .../internal/NaturalIdXrefDelegate.java | 7 ++-- .../internal/StatefulPersistenceContext.java | 7 ++-- .../engine/internal/TwoPhaseLoad.java | 3 +- .../internal/CollectionLoadContext.java | 4 +- .../hibernate/engine/spi/BatchFetchQueue.java | 6 +-- .../spi/SessionFactoryDelegatingImpl.java | 28 +++++++------- .../engine/spi/SessionFactoryImplementor.java | 15 ++++++++ .../AbstractLockUpgradeEventListener.java | 3 +- ...aultInitializeCollectionEventListener.java | 3 +- .../internal/DefaultLoadEventListener.java | 5 +-- .../internal/DefaultRefreshEventListener.java | 3 +- .../org/hibernate/internal/CacheImpl.java | 10 ++--- .../internal/SessionFactoryImpl.java | 14 ++++++- .../internal/StatelessSessionImpl.java | 3 +- .../java/org/hibernate/loader/Loader.java | 3 +- .../entity/AbstractEntityPersister.java | 5 +-- ...oncurrentNaturalIdCacheStatisticsImpl.java | 11 ++++-- ...currentSecondLevelCacheStatisticsImpl.java | 27 +++++++++---- .../internal/ConcurrentStatisticsImpl.java | 20 +++++++++- .../cache/spi/NaturalIdCacheKeyTest.java | 19 +++++----- .../test/filter/DynamicFilterTest.java | 5 +-- ...opAwareCollectionRegionAccessStrategy.java | 24 ++++++------ ...onstopAwareEntityRegionAccessStrategy.java | 33 ++++++++-------- ...topAwareNaturalIdRegionAccessStrategy.java | 30 ++++++++------- .../AbstractEhcacheAccessStrategy.java | 33 +++------------- ...bstractReadWriteEhcacheAccessStrategy.java | 13 +++---- ...EhcacheCollectionRegionAccessStrategy.java | 26 +++++++++---- ...riteEhcacheEntityRegionAccessStrategy.java | 33 +++++++++------- ...eEhcacheNaturalIdRegionAccessStrategy.java | 31 +++++++++------ ...EhcacheCollectionRegionAccessStrategy.java | 24 +++++++++--- ...OnlyEhcacheEntityRegionAccessStrategy.java | 32 +++++++++++----- ...yEhcacheNaturalIdRegionAccessStrategy.java | 32 +++++++++++----- ...EhcacheCollectionRegionAccessStrategy.java | 17 ++++++++- ...riteEhcacheEntityRegionAccessStrategy.java | 24 +++++++++--- ...eEhcacheNaturalIdRegionAccessStrategy.java | 24 +++++++++--- ...EhcacheCollectionRegionAccessStrategy.java | 26 ++++++++----- ...onalEhcacheEntityRegionAccessStrategy.java | 35 +++++++++++------ ...lEhcacheNaturalIdRegionAccessStrategy.java | 34 +++++++++++------ .../collection/TransactionalAccess.java | 26 +++++++------ .../infinispan/entity/ReadOnlyAccess.java | 5 +-- .../entity/TransactionalAccess.java | 33 ++++++++-------- .../infinispan/naturalid/ReadOnlyAccess.java | 5 +-- .../naturalid/TransactionalAccess.java | 29 +++++++------- ...bstractEntityCollectionRegionTestCase.java | 3 +- .../AbstractGeneralDataRegionTestCase.java | 11 +++--- .../AbstractRegionImplTestCase.java | 7 ++-- ...ollectionRegionAccessStrategyTestCase.java | 21 ++++------ .../CollectionRegionImplTestCase.java | 11 +++--- .../TransactionalExtraAPITestCase.java | 3 +- ...actEntityRegionAccessStrategyTestCase.java | 21 +++++----- .../AbstractReadOnlyAccessTestCase.java | 7 ++-- .../AbstractTransactionalAccessTestCase.java | 8 ++-- .../entity/EntityRegionImplTestCase.java | 11 +++--- .../entity/TransactionalExtraAPITestCase.java | 5 +-- .../EntityCollectionInvalidationTestCase.java | 16 +++----- .../NaturalIdInvalidationTestCase.java | 15 +++----- .../infinispan/util/TestingKeyFactory.java | 29 ++------------ .../AbstractReadWriteAccessStrategy.java | 11 +++--- .../BaseCollectionRegionAccessStrategy.java | 12 +++--- .../cache/BaseEntityRegionAccessStrategy.java | 19 +++++----- .../BaseNaturalIdRegionAccessStrategy.java | 22 +++++------ .../cache/BaseRegionAccessStrategy.java | 17 ++++----- ...adWriteCollectionRegionAccessStrategy.java | 5 +-- ...ctReadWriteEntityRegionAccessStrategy.java | 13 +++---- ...eadWriteNaturalIdRegionAccessStrategy.java | 11 +++--- .../ReadOnlyEntityRegionAccessStrategy.java | 11 +++--- ...ReadOnlyNaturalIdRegionAccessStrategy.java | 3 +- ...adWriteCollectionRegionAccessStrategy.java | 10 +++-- .../ReadWriteEntityRegionAccessStrategy.java | 18 +++++---- ...eadWriteNaturalIdRegionAccessStrategy.java | 18 +++++---- ...ctionalCollectionRegionAccessStrategy.java | 3 +- ...ansactionalEntityRegionAccessStrategy.java | 9 ++--- ...actionalNaturalIdRegionAccessStrategy.java | 3 +- 90 files changed, 701 insertions(+), 694 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/cache/spi/CollectionCacheKey.java delete mode 100755 hibernate-core/src/main/java/org/hibernate/cache/spi/EntityCacheKey.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java 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 3c070df5baa1..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,6 @@ import org.hibernate.action.spi.BeforeTransactionCompletionProcess; import org.hibernate.action.spi.Executable; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.collection.spi.PersistentCollection; @@ -78,7 +77,7 @@ public final void beforeExecutions() throws CacheException { // the database (this action is responsible for second-level cache invalidation only) if ( persister.hasCache() ) { final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final CollectionCacheKey ck = cache.generateCacheKey( + final Object ck = cache.generateCacheKey( key, persister, session.getFactory(), @@ -131,7 +130,7 @@ protected final SessionImplementor getSession() { protected final void evict() throws CacheException { if ( persister.hasCache() ) { final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final CollectionCacheKey ck = cache.generateCacheKey( + final Object ck = cache.generateCacheKey( key, persister, session.getFactory(), @@ -175,7 +174,7 @@ private CacheCleanupProcess(Serializable key, CollectionPersister persister, Sof @Override public void doAfterTransactionCompletion(boolean success, SessionImplementor session) { final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final CollectionCacheKey ck = cache.generateCacheKey( + final Object ck = cache.generateCacheKey( key, persister, session.getFactory(), 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 d2ca5f9b8f56..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,6 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.engine.spi.EntityEntry; @@ -85,7 +84,7 @@ public void execute() throws HibernateException { version = persister.getVersion( instance ); } - final EntityCacheKey ck; + final Object ck; if ( persister.hasCache() ) { final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); ck = cache.generateCacheKey( id, persister, session.getFactory(), session.getTenantIdentifier() ); @@ -189,7 +188,7 @@ public void doAfterTransactionCompletion(boolean success, SessionImplementor ses EntityPersister entityPersister = getPersister(); if ( entityPersister.hasCache() ) { EntityRegionAccessStrategy cache = entityPersister.getCacheAccessStrategy(); - final EntityCacheKey ck = cache.generateCacheKey( + final Object ck = cache.generateCacheKey( getId(), entityPersister, session.getFactory(), 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 4061fa29bc5b..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,7 +10,6 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.engine.internal.Versioning; @@ -118,7 +117,7 @@ public void execute() throws HibernateException { ); cacheEntry = persister.getCacheEntryStructure().structure( ce ); final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final EntityCacheKey ck = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() ); + final Object ck = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() ); final boolean put = cacheInsert( persister, ck ); @@ -138,7 +137,7 @@ public void execute() throws HibernateException { markExecuted(); } - private boolean cacheInsert(EntityPersister persister, EntityCacheKey ck) { + private boolean cacheInsert(EntityPersister persister, Object ck) { try { getSession().getEventListenerManager().cachePutStart(); return persister.getCacheAccessStrategy().insert( ck, cacheEntry, version ); @@ -213,7 +212,7 @@ public void doAfterTransactionCompletion(boolean success, SessionImplementor ses if ( success && isCachePutEnabled( persister, getSession() ) ) { final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); SessionFactoryImplementor sessionFactoryImplementor = session.getFactory(); - final EntityCacheKey ck = cache.generateCacheKey( getId(), persister, sessionFactoryImplementor, session.getTenantIdentifier() ); + final Object ck = cache.generateCacheKey( getId(), persister, sessionFactoryImplementor, session.getTenantIdentifier() ); final boolean put = cacheAfterInsert( cache, ck ); if ( put && sessionFactoryImplementor.getStatistics().isStatisticsEnabled() ) { @@ -224,7 +223,7 @@ public void doAfterTransactionCompletion(boolean success, SessionImplementor ses postCommitInsert( success ); } - private boolean cacheAfterInsert(EntityRegionAccessStrategy cache, EntityCacheKey ck) { + private boolean cacheAfterInsert(EntityRegionAccessStrategy cache, Object ck) { final SessionEventListenerManager eventListenerManager = getSession().getEventListenerManager(); try { eventListenerManager.cachePutStart(); 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 4bffb3afb0e0..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,7 +11,6 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.cache.spi.entry.CacheEntry; @@ -127,7 +126,7 @@ public void execute() throws HibernateException { previousVersion = persister.getVersion( instance ); } - final EntityCacheKey ck; + final Object ck; if ( persister.hasCache() ) { final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); ck = cache.generateCacheKey( @@ -216,7 +215,7 @@ public void execute() throws HibernateException { } } - private boolean cacheUpdate(EntityPersister persister, Object previousVersion, EntityCacheKey ck) { + private boolean cacheUpdate(EntityPersister persister, Object previousVersion, Object ck) { try { getSession().getEventListenerManager().cachePutStart(); return persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion ); @@ -312,7 +311,7 @@ public void doAfterTransactionCompletion(boolean success, SessionImplementor ses final EntityPersister persister = getPersister(); if ( persister.hasCache() ) { final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final EntityCacheKey ck = cache.generateCacheKey( + final Object ck = cache.generateCacheKey( getId(), persister, session.getFactory(), @@ -334,7 +333,7 @@ public void doAfterTransactionCompletion(boolean success, SessionImplementor ses postCommitUpdate( success ); } - private boolean cacheAfterUpdate(EntityRegionAccessStrategy cache, EntityCacheKey ck) { + private boolean cacheAfterUpdate(EntityRegionAccessStrategy cache, Object ck) { SessionEventListenerManager eventListenerManager = getSession().getEventListenerManager(); try { eventListenerManager.cachePutStart(); 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 83b5254a2aa1..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,6 @@ import java.util.Set; import org.hibernate.boot.Metadata; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.service.spi.EventListenerRegistry; @@ -141,7 +140,7 @@ private void evict(Serializable id, CollectionPersister collectionPersister, Eve LOG.debug( "Evict CollectionRegion " + collectionPersister.getRole() + " for id " + id ); } CollectionRegionAccessStrategy cache = collectionPersister.getCacheAccessStrategy(); - CollectionCacheKey key = cache.generateCacheKey( + Object key = cache.generateCacheKey( id, collectionPersister, session.getFactory(), diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java index fcc060dd6fd8..d70bca553ee4 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java @@ -6,11 +6,6 @@ */ package org.hibernate.cache.internal; -import java.io.Serializable; - -import org.hibernate.cache.spi.CollectionCacheKey; -import org.hibernate.cache.spi.EntityCacheKey; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; @@ -44,16 +39,27 @@ */ public class DefaultCacheKeysFactory { - public static CollectionCacheKey createCollectionKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + public static Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { return new OldCacheKeyImplementation( id, persister.getKeyType(), persister.getRole(), tenantIdentifier, factory ); } - public static EntityCacheKey createEntityKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + public static Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { return new OldCacheKeyImplementation( id, persister.getIdentifierType(), persister.getRootEntityName(), tenantIdentifier, factory ); } - public static NaturalIdCacheKey createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + 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/internal/OldCacheKeyImplementation.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java index 2b2a00c2cebe..20098a1d8956 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java @@ -8,8 +8,6 @@ import java.io.Serializable; -import org.hibernate.cache.spi.CollectionCacheKey; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.compare.EqualsHelper; import org.hibernate.type.Type; @@ -25,8 +23,8 @@ * @author Steve Ebersole */ @Deprecated -final class OldCacheKeyImplementation implements EntityCacheKey, CollectionCacheKey, Serializable { - private final Serializable key; +final class OldCacheKeyImplementation implements Serializable { + private final Object id; private final Type type; private final String entityOrRoleName; private final String tenantId; @@ -44,12 +42,12 @@ final class OldCacheKeyImplementation implements EntityCacheKey, CollectionCache * @param factory The session factory for which we are caching */ OldCacheKeyImplementation( - final Serializable id, + 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; @@ -57,31 +55,13 @@ final class OldCacheKeyImplementation implements EntityCacheKey, CollectionCache } 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; } - @Override - public Serializable getKey() { - return key; - } - - @Override - public String getEntityName() { - //defined exclusively on EntityCacheKey - return entityOrRoleName; - } - - @Override - public String getCollectionRole() { - //defined exclusively on CollectionCacheKey - return entityOrRoleName; - } - - @Override - public String getTenantId() { - return tenantId; + public Object getId() { + return id; } @Override @@ -98,7 +78,7 @@ public boolean equals(Object 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 ); } @@ -110,6 +90,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/internal/OldNaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java index 8d3ca82f5623..8acf9de9f9b6 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java @@ -11,7 +11,6 @@ import java.io.Serializable; import java.util.Arrays; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.internal.util.ValueHolder; @@ -30,7 +29,7 @@ * @author Steve Ebersole */ @Deprecated -public class OldNaturalIdCacheKey implements NaturalIdCacheKey, Serializable { +public class OldNaturalIdCacheKey implements Serializable { private final Serializable[] naturalIdValues; private final String entityName; private final String tenantId; diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java deleted file mode 100644 index d6583060d411..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.cache.spi; - -/** - * Allows multiple entity roles to be stored in the same cache region. Also allows for composite - * keys which do not properly implement equals()/hashCode(). - * - * @author Gavin King - * @author Steve Ebersole - */ -public interface CacheKey { - -} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CollectionCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CollectionCacheKey.java deleted file mode 100644 index 7a9154b7954c..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CollectionCacheKey.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.cache.spi; - -import java.io.Serializable; - -/** - * Allows multiple collection roles to be stored in the same cache region. Also allows for composite - * keys which do not properly implement equals()/hashCode(). - * - * @author Sanne Grinovero - * @since 5.0 - */ -public interface CollectionCacheKey extends CacheKey { - - public Serializable getKey(); - - public String getCollectionRole(); - - public String getTenantId(); - -} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/EntityCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/EntityCacheKey.java deleted file mode 100755 index cee5a9319be1..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/EntityCacheKey.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.cache.spi; - -import java.io.Serializable; - -/** - * Allows multiple entity roles to be stored in the same cache region. Also allows for composite - * keys which do not properly implement equals()/hashCode(). - * - * @author Gavin King - * @author Steve Ebersole - */ -public interface EntityCacheKey extends CacheKey { - - public Serializable getKey(); - - public String getEntityName(); - - public String getTenantId(); - -} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java deleted file mode 100644 index 0f22f37e7baf..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.cache.spi; - -/** - * Defines a key for caching natural identifier resolutions into the second level cache. - * - * @author Sanne Grinovero - * @since 5.0 - */ -public interface NaturalIdCacheKey extends CacheKey { - - String getEntityName(); - - Object[] getNaturalIdValues(); - - String getTenantId(); - -} 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 8813d6a2cdda..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 @@ -6,9 +6,6 @@ */ package org.hibernate.cache.spi.access; -import java.io.Serializable; - -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.collection.CollectionPersister; @@ -26,7 +23,7 @@ * @author Gavin King * @author Steve Ebersole */ -public interface CollectionRegionAccessStrategy extends RegionAccessStrategy { +public interface CollectionRegionAccessStrategy extends RegionAccessStrategy { /** * To create instances of CollectionCacheKey for this region, Hibernate will invoke this method @@ -37,7 +34,15 @@ public interface CollectionRegionAccessStrategy extends RegionAccessStrategy { +public interface EntityRegionAccessStrategy extends RegionAccessStrategy { /** * To create instances of EntityCacheKey for this region, Hibernate will invoke this method @@ -41,7 +38,15 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy { +public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy { /** * To create instances of NaturalIdCacheKey for this region, Hibernate will invoke this method @@ -47,7 +46,15 @@ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy { +public interface RegionAccessStrategy { /** * Attempt to retrieve an object from the cache. Mainly used in attempting @@ -26,7 +25,7 @@ public interface RegionAccessStrategy { * @return the cached object or null * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - Object get(T key, long txTimestamp) throws CacheException; + Object get(Object key, long txTimestamp) throws CacheException; /** * Attempt to cache an object, after loading from the database. @@ -39,7 +38,7 @@ public interface RegionAccessStrategy { * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ boolean putFromLoad( - T key, + Object key, Object value, long txTimestamp, Object version) throws CacheException; @@ -57,7 +56,7 @@ boolean putFromLoad( * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ boolean putFromLoad( - T key, + Object key, Object value, long txTimestamp, Object version, @@ -76,7 +75,7 @@ boolean putFromLoad( * @return A representation of our lock on the item; or null. * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - SoftLock lockItem(T key, Object version) throws CacheException; + SoftLock lockItem(Object key, Object version) throws CacheException; /** * Lock the entire region @@ -95,7 +94,7 @@ boolean putFromLoad( * @param lock The lock previously obtained from {@link #lockItem} * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - void unlockItem(T key, SoftLock lock) throws CacheException; + void unlockItem(Object key, SoftLock lock) throws CacheException; /** * Called after we have finished the attempted invalidation of the entire @@ -113,7 +112,7 @@ boolean putFromLoad( * @param key The key of the item to remove * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - void remove(T key) throws CacheException; + void remove(Object key) throws CacheException; /** * Called to evict data from the entire region @@ -129,7 +128,7 @@ boolean putFromLoad( * @param key The key of the item to remove * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} */ - void evict(T key) throws CacheException; + void evict(Object key) throws CacheException; /** * Forcibly evict all items from the cache immediately without regard for transaction 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 06cfcc0cb8d0..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,7 +8,6 @@ import java.io.Serializable; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.access.RegionAccessStrategy; import org.hibernate.engine.spi.SessionEventListenerManager; import org.hibernate.engine.spi.SessionImplementor; @@ -22,10 +21,10 @@ public final class CacheHelper { private CacheHelper() { } - public static Serializable fromSharedCache( + public static Serializable fromSharedCache( SessionImplementor session, - T cacheKey, - RegionAccessStrategy cacheAccessStrategy) { + Object cacheKey, + RegionAccessStrategy cacheAccessStrategy) { final SessionEventListenerManager eventListenerManager = session.getEventListenerManager(); Serializable cachedValue = null; eventListenerManager.cacheGetStart(); 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 bc1f9f504099..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 = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() ); + final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() ); naturalIdCacheAccessStrategy.evict( naturalIdCacheKey ); if ( sessionCachedNaturalIdValues != null && !Arrays.equals( sessionCachedNaturalIdValues, naturalIdValues ) ) { - final NaturalIdCacheKey sessionNaturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( sessionCachedNaturalIdValues, persister, session() ); + final Object sessionNaturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( sessionCachedNaturalIdValues, persister, session() ); naturalIdCacheAccessStrategy.evict( sessionNaturalIdCacheKey ); } } @@ -240,7 +239,7 @@ public Serializable findCachedNaturalIdResolution(EntityPersister persister, Obj // Try resolution from second-level cache final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy(); - final NaturalIdCacheKey naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() ); + final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() ); pk = CacheHelper.fromSharedCache( session(), naturalIdCacheKey, naturalIdCacheAccessStrategy ); 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 b6b1d8cec68f..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 = naturalIdCacheAccessStrategy.generateCacheKey( 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 = naturalIdCacheAccessStrategy.generateCacheKey( 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 = naturalIdCacheAccessStrategy.generateCacheKey( 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 1bbbd1148f63..21bf12fec1b2 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,7 +13,6 @@ import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.engine.spi.EntityEntry; @@ -185,7 +184,7 @@ private static void doInitializeEntity( final Object version = Versioning.getVersion( hydratedState, persister ); final CacheEntry entry = persister.buildCacheEntry( entity, hydratedState, version, session ); final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final EntityCacheKey cacheKey = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() ); + 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 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 0d13051b8277..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,8 +17,6 @@ import org.hibernate.CacheMode; import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CollectionCacheKey; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.entry.CollectionCacheEntry; import org.hibernate.collection.spi.PersistentCollection; @@ -335,7 +333,7 @@ private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersiste final CollectionCacheEntry entry = new CollectionCacheEntry( lce.getCollection(), persister ); final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final CollectionCacheKey cacheKey = cache.generateCacheKey( + final Object cacheKey = cache.generateCacheKey( lce.getKey(), persister, session.getFactory(), 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 245b0ae98bcb..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,8 +14,6 @@ import java.util.Map.Entry; import org.hibernate.EntityMode; -import org.hibernate.cache.spi.CollectionCacheKey; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.collection.spi.PersistentCollection; @@ -207,7 +205,7 @@ private boolean isCached(EntityKey entityKey, EntityPersister persister) { final SessionImplementor session = context.getSession(); if ( context.getSession().getCacheMode().isGetEnabled() && persister.hasCache() ) { final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final EntityCacheKey key = cache.generateCacheKey( + final Object key = cache.generateCacheKey( entityKey.getIdentifier(), persister, session.getFactory(), @@ -323,7 +321,7 @@ private boolean isCached(Serializable collectionKey, CollectionPersister persist SessionImplementor session = context.getSession(); if ( session.getCacheMode().isGetEnabled() && persister.hasCache() ) { CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - CollectionCacheKey cacheKey = cache.generateCacheKey( + Object cacheKey = cache.generateCacheKey( collectionKey, persister, session.getFactory(), 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 9d40e98005d2..fabdf879bf18 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 da77d0ecac1a..2a29d8213665 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 @@ -21,6 +21,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; @@ -189,6 +190,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 @@ -198,6 +206,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/event/internal/AbstractLockUpgradeEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java index bcf05f8147fe..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,6 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.ObjectDeletedException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.engine.spi.EntityEntry; @@ -64,7 +63,7 @@ protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOpt final boolean cachingEnabled = persister.hasCache(); SoftLock lock = null; - EntityCacheKey ck = null; + Object ck = null; try { if ( cachingEnabled ) { EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); 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 55bc6e10ff71..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,6 @@ import java.io.Serializable; import org.hibernate.HibernateException; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.entry.CollectionCacheEntry; import org.hibernate.collection.spi.PersistentCollection; @@ -118,7 +117,7 @@ private boolean initializeCollectionFromCache( final SessionFactoryImplementor factory = source.getFactory(); final CollectionRegionAccessStrategy cacheAccessStrategy = persister.getCacheAccessStrategy(); - final CollectionCacheKey ck = cacheAccessStrategy.generateCacheKey( id, persister, factory, source.getTenantIdentifier() ); + final Object ck = cacheAccessStrategy.generateCacheKey( id, persister, factory, source.getTenantIdentifier() ); final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() ); if ( factory.getStatistics().isStatisticsEnabled() ) { 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 23d8dfdc089b..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,6 @@ import org.hibernate.PersistentObjectException; import org.hibernate.TypeMismatchException; import org.hibernate.WrongClassException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.cache.spi.entry.CacheEntry; @@ -358,7 +357,7 @@ protected Object lockAndLoad( final LoadEventListener.LoadType options, final SessionImplementor source) { SoftLock lock = null; - final EntityCacheKey ck; + final Object ck; final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); if ( persister.hasCache() ) { ck = cache.generateCacheKey( @@ -576,7 +575,7 @@ protected Object loadFromSecondLevelCache( final SessionFactoryImplementor factory = source.getFactory(); final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final EntityCacheKey ck = cache.generateCacheKey( + final Object ck = cache.generateCacheKey( event.getEntityId(), persister, factory, 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 6ba772ef5970..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,6 @@ import org.hibernate.HibernateException; import org.hibernate.PersistentObjectException; import org.hibernate.UnresolvableObjectException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.engine.internal.Cascade; import org.hibernate.engine.internal.CascadePoint; @@ -138,7 +137,7 @@ public void onRefresh(RefreshEvent event, Map refreshedAlready) { if ( persister.hasCache() ) { final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - EntityCacheKey ck = cache.generateCacheKey( + Object ck = cache.generateCacheKey( id, persister, source.getFactory(), 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 25fe30046314..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,8 +14,6 @@ import org.hibernate.HibernateException; import org.hibernate.boot.spi.SessionFactoryOptions; -import org.hibernate.cache.spi.CollectionCacheKey; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.RegionFactory; @@ -78,7 +76,7 @@ public boolean containsEntity(String entityName, Serializable identifier) { EntityPersister p = sessionFactory.getEntityPersister( entityName ); if ( p.hasCache() ) { EntityRegionAccessStrategy cache = p.getCacheAccessStrategy(); - EntityCacheKey key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy + Object key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy return cache.getRegion().contains( key ); } else { @@ -102,7 +100,7 @@ public void evictEntity(String entityName, Serializable identifier) { ); } EntityRegionAccessStrategy cache = p.getCacheAccessStrategy(); - EntityCacheKey key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy + Object key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy cache.evict( key ); } } @@ -158,7 +156,7 @@ public boolean containsCollection(String role, Serializable ownerIdentifier) { CollectionPersister p = sessionFactory.getCollectionPersister( role ); if ( p.hasCache() ) { CollectionRegionAccessStrategy cache = p.getCacheAccessStrategy(); - CollectionCacheKey key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy + Object key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy return cache.getRegion().contains( key ); } else { @@ -177,7 +175,7 @@ public void evictCollection(String role, Serializable ownerIdentifier) { ); } CollectionRegionAccessStrategy cache = p.getCacheAccessStrategy(); - CollectionCacheKey key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy + Object key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy cache.evict( key ); } } 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 5ae0a321cebf..a99d0e222bee 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; @@ -200,6 +201,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" ); @@ -319,7 +321,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() ) { @@ -429,6 +430,7 @@ public MetadataImplementor getMetadata() { roles.add( persister.getRole() ); } } + this.collectionMetadata = Collections.unmodifiableMap( tmpCollectionMetadata ); for ( Map.Entry> entityToCollectionRoleMapEntry : inFlightEntityToCollectionRoleMap.entrySet() ) { @@ -1119,10 +1121,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 62f719e9ffd7..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,6 @@ import org.hibernate.StatelessSession; import org.hibernate.Transaction; import org.hibernate.UnresolvableObjectException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.internal.SessionEventListenerManagerImpl; @@ -272,7 +271,7 @@ public void refresh(String entityName, Object entity, LockMode lockMode) { if ( persister.hasCache() ) { final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final EntityCacheKey ck = cache.generateCacheKey( id, persister, getFactory(), getTenantIdentifier() ); + final Object ck = cache.generateCacheKey( id, persister, getFactory(), getTenantIdentifier() ); cache.evict( ck ); } String previousFetchProfile = this.getLoadQueryInfluencers().getInternalFetchProfile(); 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 8a89ab38c011..51bc9b9a2b01 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -32,7 +32,6 @@ import org.hibernate.Session; import org.hibernate.StaleObjectStateException; import org.hibernate.WrongClassException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.FilterKey; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.QueryKey; @@ -1623,7 +1622,7 @@ 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 EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - final EntityCacheKey ck = cache.generateCacheKey( + final Object ck = cache.generateCacheKey( key.getIdentifier(), persister, session.getFactory(), 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 d0f527ee1fa2..327ff5c19797 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.EntityCacheKey; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.entry.CacheEntry; @@ -907,7 +906,7 @@ public Object initializeLazyProperty(String fieldName, Object entity, SessionImp if ( session.getCacheMode().isGetEnabled() && hasCache() ) { final EntityRegionAccessStrategy cache = getCacheAccessStrategy(); - final EntityCacheKey cacheKey = cache.generateCacheKey(id, this, session.getFactory(), session.getTenantIdentifier() ); + 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 ); @@ -4271,7 +4270,7 @@ 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 EntityRegionAccessStrategy cache = getCacheAccessStrategy(); - final EntityCacheKey ck = cache.generateCacheKey( id, this, session.getFactory(), session.getTenantIdentifier() ); + 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 8c4518352b24..a6bce5e32b49 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.EntityCacheKey; 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,17 @@ 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(((EntityCacheKey) 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 771c92fcf6fb..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,19 +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; @@ -27,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 { @@ -60,14 +61,14 @@ public Object answer(InvocationOnMock invocation) throws Throwable { } }); - final NaturalIdCacheKey key = DefaultCacheKeysFactory.createNaturalIdKey( 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 f28cf9c336c6..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,6 @@ import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.entry.CollectionCacheEntry; import org.hibernate.cfg.AvailableSettings; @@ -102,7 +101,7 @@ public void testSecondLevelCachedCollectionsFiltering() { CollectionPersister persister = sessionFactory().getCollectionPersister( Salesperson.class.getName() + ".orders" ); assertTrue( "No cache for collection", persister.hasCache() ); CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy(); - CollectionCacheKey cacheKey = cache.generateCacheKey( + Object cacheKey = cache.generateCacheKey( testData.steveId, persister, sessionFactory(), @@ -121,7 +120,7 @@ public void testSecondLevelCachedCollectionsFiltering() { .uniqueResult(); assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() ); - CollectionCacheKey cacheKey2 = cache.generateCacheKey( + Object cacheKey2 = cache.generateCacheKey( testData.steveId, persister, sessionFactory(), 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 94b6457767b4..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 @@ -6,13 +6,9 @@ */ package org.hibernate.cache.ehcache.internal.nonstop; -import java.io.Serializable; - import net.sf.ehcache.constructs.nonstop.NonStopCacheException; - import org.hibernate.cache.CacheException; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -49,7 +45,7 @@ public CollectionRegion getRegion() { } @Override - public void evict(CollectionCacheKey key) throws CacheException { + public void evict(Object key) throws CacheException { try { actualStrategy.evict( key ); } @@ -69,7 +65,7 @@ public void evictAll() throws CacheException { } @Override - public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { try { return actualStrategy.get( key, txTimestamp ); } @@ -80,7 +76,7 @@ public Object get(CollectionCacheKey key, long txTimestamp) throws CacheExceptio } @Override - public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { try { return actualStrategy.lockItem( key, version ); } @@ -102,7 +98,7 @@ public SoftLock lockRegion() throws CacheException { } @Override - public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); @@ -114,7 +110,7 @@ public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestam } @Override - public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version ); } @@ -125,7 +121,7 @@ public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestam } @Override - public void remove(CollectionCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { try { actualStrategy.remove( key ); } @@ -145,7 +141,7 @@ public void removeAll() throws CacheException { } @Override - public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { try { actualStrategy.unlockItem( key, lock ); } @@ -165,8 +161,12 @@ public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); } + @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 ca3795e1f949..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 @@ -6,13 +6,9 @@ */ package org.hibernate.cache.ehcache.internal.nonstop; -import java.io.Serializable; - import net.sf.ehcache.constructs.nonstop.NonStopCacheException; - import org.hibernate.cache.CacheException; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -49,7 +45,7 @@ public EntityRegion getRegion() { } @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { try { return actualStrategy.afterInsert( key, value, version ); } @@ -60,7 +56,7 @@ public boolean afterInsert(EntityCacheKey key, Object value, Object version) thr } @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { try { return actualStrategy.afterUpdate( key, value, currentVersion, previousVersion, lock ); @@ -72,7 +68,7 @@ public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersi } @Override - public void evict(EntityCacheKey key) throws CacheException { + public void evict(Object key) throws CacheException { try { actualStrategy.evict( key ); } @@ -92,7 +88,7 @@ public void evictAll() throws CacheException { } @Override - public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { try { return actualStrategy.get( key, txTimestamp ); } @@ -103,7 +99,7 @@ public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { } @Override - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { try { return actualStrategy.insert( key, value, version ); } @@ -114,7 +110,7 @@ public boolean insert(EntityCacheKey key, Object value, Object version) throws C } @Override - public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { try { return actualStrategy.lockItem( key, version ); } @@ -136,7 +132,7 @@ public SoftLock lockRegion() throws CacheException { } @Override - public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); @@ -148,7 +144,7 @@ public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, O } @Override - public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version ); } @@ -159,7 +155,7 @@ public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, O } @Override - public void remove(EntityCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { try { actualStrategy.remove( key ); } @@ -179,7 +175,7 @@ public void removeAll() throws CacheException { } @Override - public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { try { actualStrategy.unlockItem( key, lock ); } @@ -199,7 +195,7 @@ public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { try { return actualStrategy.update( key, value, currentVersion, previousVersion ); @@ -211,7 +207,12 @@ public boolean update(EntityCacheKey key, Object value, Object currentVersion, O } @Override - public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); } + + @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 22202fe7e341..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,10 +7,8 @@ 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.NaturalIdCacheKey; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -42,7 +40,7 @@ public NonstopAwareNaturalIdRegionAccessStrategy( } @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { try { return actualStrategy.insert( key, value ); } @@ -53,7 +51,7 @@ public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException } @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean afterInsert(Object key, Object value) throws CacheException { try { return actualStrategy.afterInsert( key, value ); } @@ -64,7 +62,7 @@ public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheExce } @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { try { return actualStrategy.update( key, value ); } @@ -75,7 +73,7 @@ public boolean update(NaturalIdCacheKey key, Object value) throws CacheException } @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { try { return actualStrategy.afterUpdate( key, value, lock ); } @@ -91,7 +89,7 @@ public NaturalIdRegion getRegion() { } @Override - public void evict(NaturalIdCacheKey key) throws CacheException { + public void evict(Object key) throws CacheException { try { actualStrategy.evict( key ); } @@ -111,7 +109,7 @@ public void evictAll() throws CacheException { } @Override - public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { try { return actualStrategy.get( key, txTimestamp ); } @@ -122,7 +120,7 @@ public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException } @Override - public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { try { return actualStrategy.lockItem( key, version ); } @@ -144,7 +142,7 @@ public SoftLock lockRegion() throws CacheException { } @Override - public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); @@ -156,7 +154,7 @@ public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp } @Override - public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { try { return actualStrategy.putFromLoad( key, value, txTimestamp, version ); } @@ -167,7 +165,7 @@ public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp } @Override - public void remove(NaturalIdCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { try { actualStrategy.remove( key ); } @@ -187,7 +185,7 @@ public void removeAll() throws CacheException { } @Override - public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { try { actualStrategy.unlockItem( key, lock ); } @@ -207,8 +205,12 @@ public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + 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/AbstractEhcacheAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractEhcacheAccessStrategy.java index 8ec4bda1a224..63ed4faf2437 100644 --- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractEhcacheAccessStrategy.java +++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractEhcacheAccessStrategy.java @@ -6,21 +6,10 @@ */ package org.hibernate.cache.ehcache.internal.strategy; -import java.io.Serializable; - import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheTransactionalDataRegion; -import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.CacheKey; -import org.hibernate.cache.spi.CollectionCacheKey; -import org.hibernate.cache.spi.EntityCacheKey; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.SoftLock; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.persister.entity.EntityPersister; /** * Ultimate superclass for all Ehcache specific Hibernate AccessStrategy implementations. @@ -30,7 +19,7 @@ * @author Chris Dennis * @author Alex Snaps */ -abstract class AbstractEhcacheAccessStrategy { +abstract class AbstractEhcacheAccessStrategy { private final T region; private final SessionFactoryOptions settings; @@ -66,7 +55,7 @@ protected SessionFactoryOptions settings() { * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object) */ - public final boolean putFromLoad(K key, Object value, long txTimestamp, Object version) throws CacheException { + public final boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() ); } @@ -77,7 +66,7 @@ public final boolean putFromLoad(K key, Object value, long txTimestamp, Object v * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object, boolean) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#putFromLoad(java.lang.Object, java.lang.Object, long, java.lang.Object, boolean) */ - public abstract boolean putFromLoad(K key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public abstract boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException; /** @@ -110,7 +99,7 @@ public final void unlockRegion(SoftLock lock) throws CacheException { * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#remove(java.lang.Object) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#remove(java.lang.Object) */ - public void remove(K key) throws CacheException { + public void remove(Object key) throws CacheException { } /** @@ -131,7 +120,7 @@ public final void removeAll() throws CacheException { * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#evict(java.lang.Object) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#evict(java.lang.Object) */ - public final void evict(K key) throws CacheException { + public final void evict(Object key) throws CacheException { region.remove( key ); } @@ -145,16 +134,4 @@ public final void evict(K key) throws CacheException { public final void evictAll() throws CacheException { region.clear(); } - - public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { - return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); - } - - public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { - return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); - } - - public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { - return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); - } } 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 81b6324676a8..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 @@ -15,7 +15,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.EhCacheMessageLogger; import org.hibernate.cache.ehcache.internal.regions.EhcacheTransactionalDataRegion; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.access.SoftLock; import org.jboss.logging.Logger; @@ -27,8 +26,8 @@ * @author Chris Dennis * @author Alex Snaps */ -abstract class AbstractReadWriteEhcacheAccessStrategy - extends AbstractEhcacheAccessStrategy { +abstract class AbstractReadWriteEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy { private static final EhCacheMessageLogger LOG = Logger.getMessageLogger( EhCacheMessageLogger.class, @@ -55,7 +54,7 @@ public AbstractReadWriteEhcacheAccessStrategy(T region, SessionFactoryOptions se * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#get(java.lang.Object, long) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#get(java.lang.Object, long) */ - public final Object get(K key, long txTimestamp) throws CacheException { + public final Object get(Object key, long txTimestamp) throws CacheException { readLockIfNeeded( key ); try { final Lockable item = (Lockable) region().get( key ); @@ -82,7 +81,7 @@ public final Object get(K key, long txTimestamp) throws CacheException { */ @Override public final boolean putFromLoad( - K key, + Object key, Object value, long txTimestamp, Object version, @@ -111,7 +110,7 @@ public final boolean putFromLoad( * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#lockItem(java.lang.Object, java.lang.Object) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#lockItem(java.lang.Object, java.lang.Object) */ - public final SoftLock lockItem(K key, Object version) throws CacheException { + public final SoftLock lockItem(Object key, Object version) throws CacheException { region().writeLock( key ); try { final Lockable item = (Lockable) region().get( key ); @@ -135,7 +134,7 @@ public final SoftLock lockItem(K key, Object version) throws CacheException { * @see org.hibernate.cache.spi.access.EntityRegionAccessStrategy#unlockItem(java.lang.Object, org.hibernate.cache.spi.access.SoftLock) * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#unlockItem(java.lang.Object, org.hibernate.cache.spi.access.SoftLock) */ - public final void unlockItem(K key, SoftLock lock) throws CacheException { + public final void unlockItem(Object key, SoftLock lock) throws CacheException { region().writeLock( key ); try { final Lockable item = (Lockable) region().get( key ); 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 be0854bbf11d..b7278bad9d16 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,10 +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.spi.CollectionCacheKey; +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 @@ -21,7 +23,7 @@ * @author Alex Snaps */ public class NonStrictReadWriteEhcacheCollectionRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements CollectionRegionAccessStrategy { /** @@ -40,12 +42,12 @@ public CollectionRegion getRegion() { } @Override - public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -62,7 +64,7 @@ public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestam * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @@ -72,12 +74,22 @@ public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheExc * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { region().remove( key ); } @Override - public void remove(CollectionCacheKey key) 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 e68abd03c3b5..54e5af723acd 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 @@ -6,12 +6,10 @@ */ package org.hibernate.cache.ehcache.internal.strategy; -import java.io.Serializable; - import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion; -import org.hibernate.cache.spi.EntityCacheKey; +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; @@ -25,7 +23,7 @@ * @author Alex Snaps */ public class NonStrictReadWriteEhcacheEntityRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements EntityRegionAccessStrategy { /** @@ -44,12 +42,12 @@ public EntityRegion getRegion() { } @Override - public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -66,7 +64,7 @@ public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, O * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @@ -76,7 +74,7 @@ public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheExcepti * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { region().remove( key ); } @@ -86,7 +84,7 @@ public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException * Returns false since this is an asynchronous cache access strategy. */ @Override - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { return false; } @@ -96,7 +94,7 @@ public boolean insert(EntityCacheKey key, Object value, Object version) throws C * Returns false since this is a non-strict read/write cache access strategy */ @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { return false; } @@ -106,22 +104,31 @@ public boolean afterInsert(EntityCacheKey key, Object value, Object version) thr * Removes the entry since this is a non-strict read/write cache strategy. */ @Override - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { remove( key ); return false; } @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { unlockItem( key, lock ); return false; } @Override - public void remove(EntityCacheKey key) throws CacheException { + 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 55370872530b..2999c3d3a39f 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,7 +9,7 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion; -import org.hibernate.cache.spi.NaturalIdCacheKey; +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; @@ -23,7 +23,7 @@ * @author Alex Snaps */ public class NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements NaturalIdRegionAccessStrategy { /** @@ -42,12 +42,12 @@ public NaturalIdRegion getRegion() { } @Override - public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -64,7 +64,7 @@ public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @@ -74,7 +74,7 @@ public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheExce * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { region().remove( key ); } @@ -84,7 +84,7 @@ public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheExcepti * Returns false since this is an asynchronous cache access strategy. */ @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { return false; } @@ -94,7 +94,7 @@ public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException * Returns false since this is a non-strict read/write cache access strategy */ @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean afterInsert(Object key, Object value) throws CacheException { return false; } @@ -104,20 +104,29 @@ public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheExce * Removes the entry since this is a non-strict read/write cache strategy. */ @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { remove( key ); return false; } @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { unlockItem( key, lock ); return false; } @Override - public void remove(NaturalIdCacheKey key) throws CacheException { + 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 0b048b24fdcf..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,10 +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.spi.CollectionCacheKey; +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 @@ -21,7 +23,7 @@ * @author Alex Snaps */ public class ReadOnlyEhcacheCollectionRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements CollectionRegionAccessStrategy { /** @@ -40,12 +42,12 @@ public CollectionRegion getRegion() { } @Override - public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -57,7 +59,7 @@ public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestam } @Override - public SoftLock lockItem(CollectionCacheKey key, Object version) throws UnsupportedOperationException { + public SoftLock lockItem(Object key, Object version) throws UnsupportedOperationException { return null; } @@ -67,6 +69,16 @@ public SoftLock lockItem(CollectionCacheKey key, Object version) throws Unsuppor * A no-op since this cache is read-only */ @Override - public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { + 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 a09bbafb3012..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,10 +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.spi.EntityCacheKey; +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 @@ -20,7 +22,7 @@ * @author Chris Dennis * @author Alex Snaps */ -public class ReadOnlyEhcacheEntityRegionAccessStrategy extends AbstractEhcacheAccessStrategy +public class ReadOnlyEhcacheEntityRegionAccessStrategy extends AbstractEhcacheAccessStrategy implements EntityRegionAccessStrategy { /** @@ -39,12 +41,12 @@ public EntityRegion getRegion() { } @Override - public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -56,7 +58,7 @@ public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, O } @Override - public SoftLock lockItem(EntityCacheKey key, Object version) throws UnsupportedOperationException { + public SoftLock lockItem(Object key, Object version) throws UnsupportedOperationException { return null; } @@ -66,7 +68,7 @@ public SoftLock lockItem(EntityCacheKey key, Object version) throws UnsupportedO * A no-op since this cache is read-only */ @Override - public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { evict( key ); } @@ -76,12 +78,12 @@ public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException * This cache is asynchronous hence a no-op */ @Override - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { return false; } @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { region().put( key, value ); return true; } @@ -94,7 +96,7 @@ public boolean afterInsert(EntityCacheKey key, Object value, Object version) thr * @throws UnsupportedOperationException always */ @Override - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws UnsupportedOperationException { throw new UnsupportedOperationException( "Can't write to a readonly object" ); } @@ -107,8 +109,18 @@ public boolean update(EntityCacheKey key, Object value, Object currentVersion, O * @throws UnsupportedOperationException always */ @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) 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 0a0e26cfff90..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,10 +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.spi.NaturalIdCacheKey; +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 @@ -21,7 +23,7 @@ * @author Alex Snaps */ public class ReadOnlyEhcacheNaturalIdRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements NaturalIdRegionAccessStrategy { /** @@ -40,12 +42,12 @@ public NaturalIdRegion getRegion() { } @Override - public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return region().get( key ); } @Override - public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( minimalPutOverride && region().contains( key ) ) { return false; @@ -57,7 +59,7 @@ public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp } @Override - public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws UnsupportedOperationException { + public SoftLock lockItem(Object key, Object version) throws UnsupportedOperationException { return null; } @@ -67,7 +69,7 @@ public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws Unsupport * A no-op since this cache is read-only */ @Override - public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { region().remove( key ); } @@ -77,12 +79,12 @@ public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheExcepti * This cache is asynchronous hence a no-op */ @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { return false; } @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean afterInsert(Object key, Object value) throws CacheException { region().put( key, value ); return true; } @@ -95,7 +97,7 @@ public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheExce * @throws UnsupportedOperationException always */ @Override - public boolean update(NaturalIdCacheKey key, Object value) throws UnsupportedOperationException { + public boolean update(Object key, Object value) throws UnsupportedOperationException { throw new UnsupportedOperationException( "Can't write to a readonly object" ); } @@ -107,7 +109,17 @@ public boolean update(NaturalIdCacheKey key, Object value) throws UnsupportedOpe * @throws UnsupportedOperationException always */ @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws UnsupportedOperationException { + 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 acd70b501899..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,9 +8,11 @@ import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion; -import org.hibernate.cache.spi.CollectionCacheKey; +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 @@ -19,7 +21,7 @@ * @author Alex Snaps */ public class ReadWriteEhcacheCollectionRegionAccessStrategy - extends AbstractReadWriteEhcacheAccessStrategy + extends AbstractReadWriteEhcacheAccessStrategy implements CollectionRegionAccessStrategy { /** @@ -36,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 7b0a088ba8b8..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,10 +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.spi.EntityCacheKey; +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 @@ -21,7 +23,7 @@ * @author Alex Snaps */ public class ReadWriteEhcacheEntityRegionAccessStrategy - extends AbstractReadWriteEhcacheAccessStrategy + extends AbstractReadWriteEhcacheAccessStrategy implements EntityRegionAccessStrategy { /** @@ -45,7 +47,7 @@ public EntityRegion getRegion() { * A no-op since this is an asynchronous cache access strategy. */ @Override - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { return false; } @@ -55,7 +57,7 @@ public boolean insert(EntityCacheKey key, Object value, Object version) throws C * Inserts will only succeed if there is no existing value mapped to this key. */ @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { region().writeLock( key ); try { final Lockable item = (Lockable) region().get( key ); @@ -78,7 +80,7 @@ public boolean afterInsert(EntityCacheKey key, Object value, Object version) thr * A no-op since this is an asynchronous cache access strategy. */ @Override - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return false; } @@ -91,7 +93,7 @@ public boolean update(EntityCacheKey key, Object value, Object currentVersion, O * the course of this transaction. */ @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { //what should we do with previousVersion here? region().writeLock( key ); @@ -118,4 +120,14 @@ public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersi 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 86629de1da4f..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,10 +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.spi.NaturalIdCacheKey; +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 @@ -21,7 +23,7 @@ * @author Alex Snaps */ public class ReadWriteEhcacheNaturalIdRegionAccessStrategy - extends AbstractReadWriteEhcacheAccessStrategy + extends AbstractReadWriteEhcacheAccessStrategy implements NaturalIdRegionAccessStrategy { /** @@ -45,7 +47,7 @@ public NaturalIdRegion getRegion() { * A no-op since this is an asynchronous cache access strategy. */ @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { return false; } @@ -55,7 +57,7 @@ public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException * Inserts will only succeed if there is no existing value mapped to this key. */ @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean afterInsert(Object key, Object value) throws CacheException { region().writeLock( key ); try { final Lockable item = (Lockable) region().get( key ); @@ -78,7 +80,7 @@ public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheExce * A no-op since this is an asynchronous cache access strategy. */ @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { return false; } @@ -90,7 +92,7 @@ public boolean update(NaturalIdCacheKey key, Object value) throws CacheException * the course of this transaction. */ @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { //what should we do with previousVersion here? region().writeLock( key ); try { @@ -116,4 +118,14 @@ public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) t 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 fa474b770d86..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 @@ -6,15 +6,12 @@ */ package org.hibernate.cache.ehcache.internal.strategy; -import java.io.Serializable; - 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.spi.CollectionCacheKey; +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; @@ -29,7 +26,7 @@ * @author Alex Snaps */ public class TransactionalEhcacheCollectionRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements CollectionRegionAccessStrategy { private final Ehcache ehcache; @@ -50,7 +47,7 @@ public TransactionalEhcacheCollectionRegionAccessStrategy( } @Override - public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { try { final Element element = ehcache.get( key ); return element == null ? null : element.getObjectValue(); @@ -66,13 +63,13 @@ public CollectionRegion getRegion() { } @Override - public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @Override public boolean putFromLoad( - CollectionCacheKey key, + Object key, Object value, long txTimestamp, Object version, @@ -91,7 +88,7 @@ public boolean putFromLoad( } @Override - public void remove(CollectionCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { try { ehcache.remove( key ); } @@ -101,8 +98,17 @@ public void remove(CollectionCacheKey key) throws CacheException { } @Override - public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { + 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 9f38d620c8d2..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,14 +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.spi.EntityCacheKey; +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. @@ -24,7 +25,7 @@ * @author Ludovic Orban * @author Alex Snaps */ -public class TransactionalEhcacheEntityRegionAccessStrategy extends AbstractEhcacheAccessStrategy +public class TransactionalEhcacheEntityRegionAccessStrategy extends AbstractEhcacheAccessStrategy implements EntityRegionAccessStrategy { private final Ehcache ehcache; @@ -45,17 +46,17 @@ public TransactionalEhcacheEntityRegionAccessStrategy( } @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) { + public boolean afterInsert(Object key, Object value, Object version) { return false; } @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { return false; } @Override - public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { try { final Element element = ehcache.get( key ); return element == null ? null : element.getObjectValue(); @@ -71,7 +72,7 @@ public EntityRegion getRegion() { } @Override - public boolean insert(EntityCacheKey key, Object value, Object version) + public boolean insert(Object key, Object value, Object version) throws CacheException { //OptimisticCache? versioning? try { @@ -84,13 +85,13 @@ public boolean insert(EntityCacheKey key, Object value, Object version) } @Override - public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @Override public boolean putFromLoad( - EntityCacheKey key, + Object key, Object value, long txTimestamp, Object version, @@ -109,7 +110,7 @@ public boolean putFromLoad( } @Override - public void remove(EntityCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { try { ehcache.remove( key ); } @@ -119,13 +120,13 @@ public void remove(EntityCacheKey key) throws CacheException { } @Override - public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { // no-op } @Override public boolean update( - EntityCacheKey key, + Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { @@ -137,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 64b1606fed8d..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,14 +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.spi.NaturalIdCacheKey; +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. @@ -25,7 +26,7 @@ * @author Alex Snaps */ public class TransactionalEhcacheNaturalIdRegionAccessStrategy - extends AbstractEhcacheAccessStrategy + extends AbstractEhcacheAccessStrategy implements NaturalIdRegionAccessStrategy { private final Ehcache ehcache; @@ -46,17 +47,17 @@ public TransactionalEhcacheNaturalIdRegionAccessStrategy( } @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) { + public boolean afterInsert(Object key, Object value) { return false; } @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) { + public boolean afterUpdate(Object key, Object value, SoftLock lock) { return false; } @Override - public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { try { final Element element = ehcache.get( key ); return element == null ? null : element.getObjectValue(); @@ -72,7 +73,7 @@ public NaturalIdRegion getRegion() { } @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { //OptimisticCache? versioning? try { ehcache.put( new Element( key, value ) ); @@ -84,13 +85,13 @@ public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException } @Override - public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @Override public boolean putFromLoad( - NaturalIdCacheKey key, + Object key, Object value, long txTimestamp, Object version, @@ -109,7 +110,7 @@ public boolean putFromLoad( } @Override - public void remove(NaturalIdCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { try { ehcache.remove( key ); } @@ -119,12 +120,12 @@ public void remove(NaturalIdCacheKey key) throws CacheException { } @Override - public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { // no-op } @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { try { ehcache.put( new Element( key, value ) ); return true; @@ -134,4 +135,13 @@ public boolean update(NaturalIdCacheKey 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 7f928e859ed6..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 @@ -6,12 +6,9 @@ */ package org.hibernate.cache.infinispan.collection; -import java.io.Serializable; - import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -36,7 +33,7 @@ class TransactionalAccess implements CollectionRegionAccessStrategy { this.delegate = new TransactionalAccessDelegate( region, region.getPutFromLoadValidator() ); } - public void evict(CollectionCacheKey key) throws CacheException { + public void evict(Object key) throws CacheException { delegate.evict( key ); } @@ -44,20 +41,20 @@ public void evictAll() throws CacheException { delegate.evictAll(); } - public Object get(CollectionCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return delegate.get( key, txTimestamp ); } - public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version ); } - public boolean putFromLoad(CollectionCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); } - public void remove(CollectionCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { delegate.remove( key ); } @@ -69,7 +66,7 @@ public CollectionRegion getRegion() { return region; } - public SoftLock lockItem(CollectionCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @@ -77,15 +74,20 @@ public SoftLock lockRegion() throws CacheException { return null; } - public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { } public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { - return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); + 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/ReadOnlyAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java index a034899fcb91..38da0a84b5ed 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java @@ -7,7 +7,6 @@ package org.hibernate.cache.infinispan.entity; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -26,14 +25,14 @@ class ReadOnlyAccess extends TransactionalAccess { @Override public boolean update( - EntityCacheKey key, Object value, Object currentVersion, + Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); } @Override public boolean afterUpdate( - EntityCacheKey key, Object value, Object currentVersion, + Object key, Object value, Object currentVersion, Object previousVersion, 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/entity/TransactionalAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java index 2d5bf8319306..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 @@ -6,12 +6,9 @@ */ package org.hibernate.cache.infinispan.entity; -import java.io.Serializable; - import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -36,7 +33,7 @@ class TransactionalAccess implements EntityRegionAccessStrategy { this.delegate = new TransactionalAccessDelegate( region, region.getPutFromLoadValidator() ); } - public void evict(EntityCacheKey key) throws CacheException { + public void evict(Object key) throws CacheException { delegate.evict( key ); } @@ -44,7 +41,7 @@ public void evictAll() throws CacheException { delegate.evictAll(); } - public Object get(EntityCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return delegate.get( key, txTimestamp ); } @@ -52,20 +49,20 @@ public EntityRegion getRegion() { return this.region; } - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { return delegate.insert( key, value, version ); } - public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version ); } - public boolean putFromLoad(EntityCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); } - public void remove(EntityCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { delegate.remove( key ); } @@ -73,12 +70,12 @@ public void removeAll() throws CacheException { delegate.removeAll(); } - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return delegate.update( key, value, currentVersion, previousVersion ); } - public SoftLock lockItem(EntityCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @@ -86,24 +83,28 @@ public SoftLock lockRegion() throws CacheException { return null; } - public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { } public void unlockRegion(SoftLock lock) throws CacheException { } - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { return false; } - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { return false; } @Override - public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { - return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); + 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 bef04363d164..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 @@ -7,7 +7,6 @@ package org.hibernate.cache.infinispan.naturalid; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -20,12 +19,12 @@ class ReadOnlyAccess extends TransactionalAccess { } @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); } @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) 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 bd0ba14fbfc5..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 @@ -9,7 +9,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -29,12 +28,12 @@ class TransactionalAccess implements NaturalIdRegionAccessStrategy { } @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { return delegate.insert( key, value, null ); } @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { return delegate.update( key, value, null, null ); } @@ -44,7 +43,7 @@ public NaturalIdRegion getRegion() { } @Override - public void evict(NaturalIdCacheKey key) throws CacheException { + public void evict(Object key) throws CacheException { delegate.evict( key ); } @@ -54,23 +53,23 @@ public void evictAll() throws CacheException { } @Override - public Object get(NaturalIdCacheKey key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return delegate.get( key, txTimestamp ); } @Override - public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version ); } @Override - public boolean putFromLoad(NaturalIdCacheKey key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { return delegate.putFromLoad( key, value, txTimestamp, version, minimalPutOverride ); } @Override - public void remove(NaturalIdCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { delegate.remove( key ); } @@ -80,7 +79,7 @@ public void removeAll() throws CacheException { } @Override - public SoftLock lockItem(NaturalIdCacheKey key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @@ -90,7 +89,7 @@ public SoftLock lockRegion() throws CacheException { } @Override - public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { } @Override @@ -98,18 +97,22 @@ public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean afterInsert(Object key, Object value) throws CacheException { return false; } @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { return false; } @Override - public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + 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 fd48bbb4e1cd..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 @@ -12,7 +12,6 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.spi.CacheDataDescription; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; import org.hibernate.cache.spi.access.AccessType; @@ -29,7 +28,7 @@ * @author Galder Zamarreño * @since 3.5 */ -public abstract class AbstractEntityCollectionRegionTestCase extends AbstractRegionImplTestCase { +public abstract class AbstractEntityCollectionRegionTestCase extends AbstractRegionImplTestCase { @Test public void testSupportedAccessTypes() throws Exception { supportedAccessTypeTest(); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractGeneralDataRegionTestCase.java index e41e243e93de..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 @@ -12,16 +12,15 @@ import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; -import org.hibernate.cache.spi.CacheKey; 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; @@ -32,7 +31,7 @@ * @author Galder Zamarreño * @since 3.5 */ -public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionImplTestCase { +public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionImplTestCase { private static final Logger log = Logger.getLogger( AbstractGeneralDataRegionTestCase.class ); protected static final String KEY = "Key"; @@ -50,12 +49,12 @@ protected StandardServiceRegistryBuilder createStandardServiceRegistryBuilder() } @Override - protected void putInRegion(Region region, T key, Object value) { + protected void putInRegion(Region region, Object key, Object value) { ((GeneralDataRegion) region).put( key, value ); } @Override - protected void removeFromRegion(Region region, T key) { + protected void removeFromRegion(Region region, Object key) { ((GeneralDataRegion) region).evict( key ); } diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java index 23c59bf62ecb..2daf5ad2e0d9 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java @@ -11,7 +11,6 @@ import org.hibernate.cache.infinispan.InfinispanRegionFactory; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.Region; import org.hibernate.internal.util.compare.ComparableComparator; import org.infinispan.AdvancedCache; @@ -22,15 +21,15 @@ * @author Galder Zamarreño * @since 3.5 */ -public abstract class AbstractRegionImplTestCase extends AbstractNonFunctionalTestCase { +public abstract class AbstractRegionImplTestCase extends AbstractNonFunctionalTestCase { protected abstract AdvancedCache getInfinispanCache(InfinispanRegionFactory regionFactory); protected abstract Region createRegion(InfinispanRegionFactory regionFactory, String regionName, Properties properties, CacheDataDescription cdd); - protected abstract void putInRegion(Region region, T key, Object value); + protected abstract void putInRegion(Region region, Object key, Object value); - protected abstract void removeFromRegion(Region region, T key); + protected abstract void removeFromRegion(Region region, Object key); protected CacheDataDescription getCacheDataDescription() { return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE); 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 efa2eb66d09d..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,6 +6,7 @@ */ 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; @@ -13,8 +14,7 @@ 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; @@ -23,7 +23,6 @@ import org.hibernate.cache.infinispan.util.Caches; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.internal.util.compare.ComparableComparator; @@ -31,16 +30,13 @@ 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; - -import junit.framework.AssertionFailedError; - 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; @@ -56,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"; @@ -232,7 +227,7 @@ public void testPutFromLoadMinimal() throws Exception { private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { - final CollectionCacheKey KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ ); + final Object KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ ); final CountDownLatch writeLatch1 = new CountDownLatch( 1 ); final CountDownLatch writeLatch2 = new CountDownLatch( 1 ); @@ -384,7 +379,7 @@ public void testEvictAll() throws Exception { private void evictOrRemoveTest(final boolean evict) throws Exception { - final CollectionCacheKey KEY = TestingKeyFactory.generateCollectionCacheKey( 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() ) ); @@ -415,7 +410,7 @@ public Void call() throws Exception { private void evictOrRemoveAllTest(final boolean evict) throws Exception { - final CollectionCacheKey KEY = TestingKeyFactory.generateCollectionCacheKey( 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 88373f3f65f9..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,11 +6,12 @@ */ 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; import org.hibernate.cache.spi.CacheDataDescription; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.RegionFactory; @@ -19,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,7 +28,7 @@ * * @author Galder Zamarreño */ -public class CollectionRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { +public class CollectionRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); @@ -62,13 +61,13 @@ protected AdvancedCache getInfinispanCache(InfinispanRegionFactory regionFactory } @Override - protected void putInRegion(Region region, CollectionCacheKey key, Object value) { + protected void putInRegion(Region region, Object key, Object value) { CollectionRegionAccessStrategy strategy = ((CollectionRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL); strategy.putFromLoad(key, value, System.currentTimeMillis(), new Integer(1)); } @Override - protected void removeFromRegion(Region region, CollectionCacheKey key) { + protected void removeFromRegion(Region region, Object key) { ((CollectionRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).remove(key); } 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 b8b63c473fc6..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 @@ -8,7 +8,6 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -31,7 +30,7 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase { public static final String REGION_NAME = "test/com.foo.test"; - public static final CollectionCacheKey KEY = TestingKeyFactory.generateCollectionCacheKey( "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 90e0a8178272..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,13 +11,13 @@ 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; import org.hibernate.cache.infinispan.util.Caches; import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.internal.util.compare.ComparableComparator; @@ -25,16 +25,13 @@ 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; - -import junit.framework.AssertionFailedError; - 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; @@ -194,7 +191,7 @@ public void testPutFromLoadMinimal() throws Exception { */ private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { - final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final CountDownLatch writeLatch1 = new CountDownLatch(1); final CountDownLatch writeLatch2 = new CountDownLatch(1); @@ -298,7 +295,7 @@ public void run() { @Test public void testInsert() throws Exception { - final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); final CountDownLatch readLatch = new CountDownLatch(1); final CountDownLatch commitLatch = new CountDownLatch(1); @@ -387,7 +384,7 @@ public void run() { @Test public void testUpdate() throws Exception { - final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); // Set up initial state localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); @@ -503,7 +500,7 @@ public void testEvictAll() throws Exception { } private void evictOrRemoveTest(final boolean evict) throws Exception { - final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); assertEquals(0, getValidKeyCount(localEntityRegion.getCache().keySet())); assertEquals(0, getValidKeyCount(remoteEntityRegion.getCache().keySet())); @@ -532,7 +529,7 @@ public Void call() throws Exception { } private void evictOrRemoveAllTest(final boolean evict) throws Exception { - final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( 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 d6dd77ff13b1..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 @@ -6,11 +6,10 @@ */ package org.hibernate.test.cache.infinispan.entity; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.test.cache.infinispan.util.TestingKeyFactory; -import org.junit.Test; 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 EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); + final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); @@ -64,7 +63,7 @@ private void putFromLoadTest(boolean minimal) throws Exception { @Test(expected = UnsupportedOperationException.class) @Override public void testUpdate() throws Exception { - final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ ); + 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 87e549a18d2e..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,12 +10,10 @@ import java.util.concurrent.TimeUnit; import junit.framework.AssertionFailedError; - -import org.infinispan.transaction.tm.BatchModeTransactionManager; -import org.jboss.logging.Logger; -import org.hibernate.cache.spi.EntityCacheKey; 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 static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -36,7 +34,7 @@ protected AccessType getAccessType() { public void testContestedPutFromLoad() throws Exception { - final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( 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 0ba2b2310e8b..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,11 +6,12 @@ */ 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; import org.hibernate.cache.spi.CacheDataDescription; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.RegionFactory; @@ -18,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,7 +28,7 @@ * @author Galder Zamarreño * @since 3.5 */ -public class EntityRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { +public class EntityRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); @@ -52,12 +51,12 @@ protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties p } @Override - protected void putInRegion(Region region, EntityCacheKey key, Object value) { + protected void putInRegion(Region region, Object key, Object value) { ((EntityRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).insert(key, value, 1); } @Override - protected void removeFromRegion(Region region, EntityCacheKey key) { + protected void removeFromRegion(Region region, Object key) { ((EntityRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).remove(key); } 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 cb86be8a48af..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,9 +7,8 @@ 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.spi.EntityCacheKey; +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; @@ -36,7 +35,7 @@ */ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase { public static final String REGION_NAME = "test/com.foo.test"; - public static final EntityCacheKey KEY = TestingKeyFactory.generateEntityCacheKey( "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 f6e6ef39da7b..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,12 +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,11 +24,6 @@ import org.infinispan.util.logging.LogFactory; import org.jboss.util.collection.ConcurrentSet; import org.junit.Test; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.cache.spi.EntityCacheKey; -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() ) { - EntityCacheKey cacheKey = (EntityCacheKey) event.getKey(); - Integer primKey = (Integer) cacheKey.getKey(); - String key = cacheKey.getEntityName() + '#' + 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 index 61b3dbe14fcc..26c695d8b1be 100644 --- 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 @@ -8,25 +8,22 @@ import java.io.Serializable; -import org.hibernate.cache.spi.CollectionCacheKey; -import org.hibernate.cache.spi.EntityCacheKey; - public class TestingKeyFactory { private TestingKeyFactory() { //Not to be constructed } - public static EntityCacheKey generateEntityCacheKey(String id) { + public static Object generateEntityCacheKey(String id) { return new TestingEntityCacheKey( id ); } - public static CollectionCacheKey generateCollectionCacheKey(String id) { + public static Object generateCollectionCacheKey(String id) { return new TestingEntityCacheKey( id ); } //For convenience implement both interfaces. - private static class TestingEntityCacheKey implements EntityCacheKey, CollectionCacheKey, Serializable { + private static class TestingEntityCacheKey implements Serializable { private final String id; @@ -34,26 +31,6 @@ public TestingEntityCacheKey(String id) { this.id = id; } - @Override - public Serializable getKey() { - return null; - } - - @Override - public String getEntityName() { - return null; - } - - @Override - public String getCollectionRole() { - return null; - } - - @Override - public String getTenantId() { - return null; - } - @Override public int hashCode() { final int prime = 31; diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java index e62c826ad4ae..ec2c2713cf26 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/AbstractReadWriteAccessStrategy.java @@ -13,7 +13,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.access.SoftLock; import org.jboss.logging.Logger; @@ -21,7 +20,7 @@ /** * @author Strong Liu */ -abstract class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy { +abstract class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy { private static final Logger LOG = Logger.getLogger( AbstractReadWriteAccessStrategy.class.getName() ); private final UUID uuid = UUID.randomUUID(); @@ -35,7 +34,7 @@ abstract class AbstractReadWriteAccessStrategy extends BaseR * after the start of this transaction. */ @Override - public final Object get(T key, long txTimestamp) throws CacheException { + public final Object get(Object key, long txTimestamp) throws CacheException { LOG.debugf( "getting key[%s] from region[%s]", key, getInternalRegion().getName() ); try { readLock.lock(); @@ -69,7 +68,7 @@ public final Object get(T key, long txTimestamp) throws CacheException { */ @Override public final boolean putFromLoad( - T key, + Object key, Object value, long txTimestamp, Object version, @@ -109,7 +108,7 @@ public final boolean putFromLoad( * Soft-lock a cache item. */ @Override - public final SoftLock lockItem(T key, Object version) throws CacheException { + public final SoftLock lockItem(Object key, Object version) throws CacheException { try { LOG.debugf( "locking key[%s] in region[%s]", key, getInternalRegion().getName() ); @@ -133,7 +132,7 @@ public final SoftLock lockItem(T key, Object version) throws CacheException { * Soft-unlock a cache item. */ @Override - public final void unlockItem(T key, SoftLock lock) throws CacheException { + public final void unlockItem(Object key, SoftLock lock) throws CacheException { try { LOG.debugf( "unlocking key[%s] in region[%s]", key, getInternalRegion().getName() ); 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 20884b070371..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,10 +6,7 @@ */ package org.hibernate.testing.cache; -import java.io.Serializable; - import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -18,7 +15,7 @@ /** * @author Strong Liu */ -class BaseCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy { +class BaseCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy { private final CollectionRegionImpl region; @@ -42,8 +39,13 @@ public CollectionRegion getRegion() { } @Override - public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); } + @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 75849b7deaa1..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 @@ -6,11 +6,8 @@ */ package org.hibernate.testing.cache; -import java.io.Serializable; - import org.hibernate.cache.CacheException; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -20,7 +17,7 @@ /** * @author Strong Liu */ -class BaseEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy { +class BaseEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy { private final EntityRegionImpl region; @@ -34,23 +31,23 @@ public EntityRegion getRegion() { } @Override - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { return putFromLoad( key, value, 0, version ); } @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { return true; } @Override - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return false; } @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { return false; } @@ -66,8 +63,12 @@ protected boolean isDefaultMinimalPutOverride() { } @Override - public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); } + @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 e360085b8f4d..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 @@ -6,23 +6,18 @@ */ package org.hibernate.testing.cache; -import java.io.Serializable; - import org.hibernate.cache.CacheException; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.NaturalIdCacheKey; 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.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.type.Type; /** * @author Eric Dalquist */ -class BaseNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy { +class BaseNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy { private final NaturalIdRegionImpl region; @Override @@ -41,22 +36,22 @@ public NaturalIdRegion getRegion() { } @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { return putFromLoad( key, value, 0, null ); } @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean afterInsert(Object key, Object value) throws CacheException { return false; } @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { return putFromLoad( key, value, 0, null ); } @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { return false; } @@ -65,7 +60,12 @@ public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) t } @Override - public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + 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 a8b6ab707bc9..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 @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.CacheKey; import org.hibernate.cache.spi.access.RegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; import org.jboss.logging.Logger; @@ -15,7 +14,7 @@ /** * @author Strong Liu */ -abstract class BaseRegionAccessStrategy implements RegionAccessStrategy { +abstract class BaseRegionAccessStrategy implements RegionAccessStrategy { private static final Logger LOG = Logger.getLogger( BaseRegionAccessStrategy.class ); @@ -24,17 +23,17 @@ abstract class BaseRegionAccessStrategy implements RegionAcc protected abstract boolean isDefaultMinimalPutOverride(); @Override - public Object get(T key, long txTimestamp) throws CacheException { + public Object get(Object key, long txTimestamp) throws CacheException { return getInternalRegion().get( key ); } @Override - public boolean putFromLoad(T key, Object value, long txTimestamp, Object version) throws CacheException { + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { return putFromLoad( key, value, txTimestamp, version, isDefaultMinimalPutOverride() ); } @Override - public boolean putFromLoad(T key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException { if ( key == null || value == null ) { @@ -75,12 +74,12 @@ public void unlockRegion(SoftLock lock) throws CacheException { } @Override - public SoftLock lockItem(T key, Object version) throws CacheException { + public SoftLock lockItem(Object key, Object version) throws CacheException { return null; } @Override - public void unlockItem(T key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { } @@ -91,7 +90,7 @@ public void unlockItem(T key, SoftLock lock) throws CacheException { * @see org.hibernate.cache.spi.access.CollectionRegionAccessStrategy#remove(java.lang.Object) */ @Override - public void remove(T key) throws CacheException { + public void remove(Object key) throws CacheException { } /** @@ -107,7 +106,7 @@ public void removeAll() throws CacheException { } @Override - public void evict(T key) throws CacheException { + public void evict(Object key) throws CacheException { getInternalRegion().evict( key ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteCollectionRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteCollectionRegionAccessStrategy.java index 58a288ca29c9..4b261979a1bf 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteCollectionRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteCollectionRegionAccessStrategy.java @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -19,12 +18,12 @@ class NonstrictReadWriteCollectionRegionAccessStrategy extends BaseCollectionReg } @Override - public void unlockItem(CollectionCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { evict( key ); } @Override - public void remove(CollectionCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { evict( key ); } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteEntityRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteEntityRegionAccessStrategy.java index 6435c9356f90..70c9c8623d2f 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteEntityRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteEntityRegionAccessStrategy.java @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -22,7 +21,7 @@ class NonstrictReadWriteEntityRegionAccessStrategy extends BaseEntityRegionAcces * Since this is a non-strict read/write strategy item locking is not used. */ @Override - public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { evict( key ); } @@ -30,7 +29,7 @@ public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException * Returns false since this is an asynchronous cache access strategy. */ @Override - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { return false; } @@ -38,7 +37,7 @@ public boolean insert(EntityCacheKey key, Object value, Object version) throws C * Returns false since this is a non-strict read/write cache access strategy */ @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { return false; } @@ -46,21 +45,21 @@ public boolean afterInsert(EntityCacheKey key, Object value, Object version) thr * Removes the entry since this is a non-strict read/write cache strategy. */ @Override - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { evict( key ); return false; } @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { unlockItem( key, lock ); return false; } @Override - public void remove(EntityCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { evict( key ); } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteNaturalIdRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteNaturalIdRegionAccessStrategy.java index 830d37269e5e..3f23270588d1 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteNaturalIdRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/NonstrictReadWriteNaturalIdRegionAccessStrategy.java @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -19,27 +18,27 @@ class NonstrictReadWriteNaturalIdRegionAccessStrategy extends BaseNaturalIdRegio } @Override - public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { evict( key ); } @Override - public void remove(NaturalIdCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { evict( key ); } @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { return false; } @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean afterInsert(Object key, Object value) throws CacheException { return false; } @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { remove( key ); return false; } 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 a3aa01ba1f94..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 @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.SoftLock; import org.jboss.logging.Logger; @@ -26,18 +25,18 @@ class ReadOnlyEntityRegionAccessStrategy extends BaseEntityRegionAccessStrategy * This cache is asynchronous hence a no-op */ @Override - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { return false; //wait until tx complete, see afterInsert(). } @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { getInternalRegion().put( key, value ); //save into cache since the tx is completed return true; } @Override - public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { evict( key ); } @@ -47,7 +46,7 @@ public void unlockItem(EntityCacheKey key, SoftLock lock) throws CacheException * @throws UnsupportedOperationException always */ @Override - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { LOG.info( "Illegal attempt to update item cached as read-only : " + key ); throw new UnsupportedOperationException( "Can't write to a readonly object" ); @@ -59,7 +58,7 @@ public boolean update(EntityCacheKey key, Object value, Object currentVersion, O * @throws UnsupportedOperationException always */ @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { LOG.info( "Illegal attempt to update item cached as read-only : " + key ); throw new UnsupportedOperationException( "Can't write to a readonly object" ); diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyNaturalIdRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyNaturalIdRegionAccessStrategy.java index 3b3a064c171c..93f3b9b7ec9a 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyNaturalIdRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/ReadOnlyNaturalIdRegionAccessStrategy.java @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -19,7 +18,7 @@ class ReadOnlyNaturalIdRegionAccessStrategy extends BaseNaturalIdRegionAccessStr } @Override - public void unlockItem(NaturalIdCacheKey key, SoftLock lock) throws CacheException { + public void unlockItem(Object key, SoftLock lock) throws CacheException { evict( key ); } } 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 ed4389f84d31..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 @@ -6,11 +6,9 @@ */ package org.hibernate.testing.cache; -import java.io.Serializable; import java.util.Comparator; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.CollectionCacheKey; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -19,7 +17,7 @@ /** * @author Strong Liu */ -class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy +class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements CollectionRegionAccessStrategy { private final CollectionRegionImpl region; @@ -49,8 +47,12 @@ public CollectionRegion getRegion() { } @Override - public CollectionCacheKey generateCacheKey(Serializable id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier ); } + @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 382f98dbb9d7..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 @@ -6,12 +6,10 @@ */ package org.hibernate.testing.cache; -import java.io.Serializable; import java.util.Comparator; import org.hibernate.cache.CacheException; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -21,7 +19,7 @@ /** * @author Strong Liu */ -class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrategy +class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements EntityRegionAccessStrategy { private final EntityRegionImpl region; @@ -30,18 +28,18 @@ class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrateg } @Override - public boolean insert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean insert(Object key, Object value, Object version) throws CacheException { return false; } @Override - public boolean update(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion) + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return false; } @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) throws CacheException { + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { try { writeLock.lock(); @@ -61,7 +59,7 @@ public boolean afterInsert(EntityCacheKey key, Object value, Object version) thr @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { try { writeLock.lock(); @@ -110,8 +108,12 @@ public EntityRegion getRegion() { } @Override - public EntityCacheKey generateCacheKey(Serializable id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier ); } + @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 2cb429c6d68e..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 @@ -10,7 +10,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.internal.DefaultCacheKeysFactory; -import org.hibernate.cache.spi.NaturalIdCacheKey; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -20,7 +19,7 @@ /** * @author Eric Dalquist */ -class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStrategy +class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements NaturalIdRegionAccessStrategy { private final NaturalIdRegionImpl region; @@ -30,17 +29,17 @@ class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStra } @Override - public boolean insert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean insert(Object key, Object value) throws CacheException { return false; } @Override - public boolean update(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean update(Object key, Object value) throws CacheException { return false; } @Override - public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheException { + public boolean afterInsert(Object key, Object value) throws CacheException { try { writeLock.lock(); @@ -60,7 +59,7 @@ public boolean afterInsert(NaturalIdCacheKey key, Object value) throws CacheExce @Override - public boolean afterUpdate(NaturalIdCacheKey key, Object value, SoftLock lock) throws CacheException { + public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException { try { writeLock.lock(); Lockable item = (Lockable) region.get( key ); @@ -107,7 +106,12 @@ public NaturalIdRegion getRegion() { } @Override - public NaturalIdCacheKey generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + 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/TransactionalCollectionRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalCollectionRegionAccessStrategy.java index 35c510cb8146..f789f70fea96 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalCollectionRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalCollectionRegionAccessStrategy.java @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.CollectionCacheKey; /** * @author Strong Liu @@ -18,7 +17,7 @@ class TransactionalCollectionRegionAccessStrategy extends BaseCollectionRegionAc } @Override - public void remove(CollectionCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { evict( key ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalEntityRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalEntityRegionAccessStrategy.java index 502b2745de25..56507eaf001a 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalEntityRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalEntityRegionAccessStrategy.java @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.EntityCacheKey; import org.hibernate.cache.spi.access.SoftLock; /** @@ -19,23 +18,23 @@ class TransactionalEntityRegionAccessStrategy extends BaseEntityRegionAccessStra } @Override - public boolean afterInsert(EntityCacheKey key, Object value, Object version) { + public boolean afterInsert(Object key, Object value, Object version) { return false; } @Override - public boolean afterUpdate(EntityCacheKey key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) { return false; } @Override - public void remove(EntityCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { evict( key ); } @Override public boolean update( - EntityCacheKey key, Object value, Object currentVersion, + Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException { return insert( key, value, currentVersion ); } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalNaturalIdRegionAccessStrategy.java b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalNaturalIdRegionAccessStrategy.java index 3ddfa1fa66e6..23e644457856 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalNaturalIdRegionAccessStrategy.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/cache/TransactionalNaturalIdRegionAccessStrategy.java @@ -7,7 +7,6 @@ package org.hibernate.testing.cache; import org.hibernate.cache.CacheException; -import org.hibernate.cache.spi.NaturalIdCacheKey; /** * @author Eric Dalquist @@ -18,7 +17,7 @@ class TransactionalNaturalIdRegionAccessStrategy extends BaseNaturalIdRegionAcce } @Override - public void remove(NaturalIdCacheKey key) throws CacheException { + public void remove(Object key) throws CacheException { evict( key ); } From 29675a4eed886c6542d824f709c5844872facb8b Mon Sep 17 00:00:00 2001 From: Radim Vansa Date: Tue, 9 Jun 2015 13:04:44 +0200 Subject: [PATCH 4/7] HHH-9843 Use optimized cache key implementation in Infinispan 2LC * When multi-tenancy is not used, entity's @Id can be used as key to the cache * Added Type to CacheDataDescription (in SPI), later used for container key equivalence * Introduced CacheKeysFactory to SPI * Pending puts cache is now per region - this is necessary as we need to use custom key equivalence --- .../internal/CacheDataDescriptionImpl.java | 20 ++- .../internal/DefaultCacheKeysFactory.java | 35 +++++- .../cache/internal/OldNaturalIdCacheKey.java | 13 +- .../internal/SimpleCacheKeysFactory.java | 54 ++++++++ .../cache/spi/CacheDataDescription.java | 8 ++ .../hibernate/cache/spi/CacheKeysFactory.java | 29 +++++ .../cache/spi/NaturalIdCacheKeyTest.java | 2 +- .../infinispan/InfinispanRegionFactory.java | 73 +++++++---- .../cache/infinispan/TypeEquivalance.java | 40 ++++++ .../access/PutFromLoadValidator.java | 45 ++++--- .../collection/CollectionRegionImpl.java | 7 +- .../collection/TransactionalAccess.java | 5 +- .../infinispan/entity/EntityRegionImpl.java | 7 +- .../entity/TransactionalAccess.java | 5 +- .../impl/BaseTransactionalDataRegion.java | 11 +- .../naturalid/NaturalIdRegionImpl.java | 7 +- .../naturalid/TransactionalAccess.java | 5 +- .../query/QueryResultsRegionImpl.java | 3 +- ...bstractEntityCollectionRegionTestCase.java | 4 + .../AbstractRegionImplTestCase.java | 2 +- .../InfinispanRegionFactoryTestCase.java | 32 +++-- .../PutFromLoadValidatorUnitTestCase.java | 33 +++-- ...ollectionRegionAccessStrategyTestCase.java | 4 +- .../CollectionRegionImplTestCase.java | 4 - .../TransactionalExtraAPITestCase.java | 9 +- ...actEntityRegionAccessStrategyTestCase.java | 2 +- .../entity/EntityRegionImplTestCase.java | 3 - .../entity/TransactionalExtraAPITestCase.java | 5 +- .../infinispan/functional/EqualityTest.java | 77 ++++++++++++ .../functional/MultiTenancyTestCase.java | 115 ++++++++++++++++++ .../cache/infinispan/functional/Name.java | 48 ++++++++ .../functional/NoTenancyTestCase.java | 56 +++++++++ .../cache/infinispan/functional/Person.java | 41 +++++++ .../EntityCollectionInvalidationTestCase.java | 4 +- 34 files changed, 686 insertions(+), 122 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java create mode 100644 hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java create mode 100644 hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/TypeEquivalance.java create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/EqualityTest.java create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Name.java create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/NoTenancyTestCase.java create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Person.java diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java index 28610c21ef75..b849330f396e 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheDataDescriptionImpl.java @@ -11,6 +11,7 @@ import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.mapping.Collection; import org.hibernate.mapping.PersistentClass; +import org.hibernate.type.Type; import org.hibernate.type.VersionType; /** @@ -22,19 +23,21 @@ public class CacheDataDescriptionImpl implements CacheDataDescription { private final boolean mutable; private final boolean versioned; private final Comparator versionComparator; + private final Type keyType; /** * Constructs a CacheDataDescriptionImpl instance. Generally speaking, code should use one of the * overloaded {@link #decode} methods rather than direct instantiation. - * * @param mutable Is the described data mutable? * @param versioned Is the described data versioned? * @param versionComparator The described data's version value comparator (if versioned). + * @param keyType */ - public CacheDataDescriptionImpl(boolean mutable, boolean versioned, Comparator versionComparator) { + public CacheDataDescriptionImpl(boolean mutable, boolean versioned, Comparator versionComparator, Type keyType) { this.mutable = mutable; this.versioned = versioned; this.versionComparator = versionComparator; + this.keyType = keyType; } @Override @@ -52,6 +55,11 @@ public Comparator getVersionComparator() { return versionComparator; } + @Override + public Type getKeyType() { + return keyType; + } + /** * Builds a CacheDataDescriptionImpl from the mapping model of an entity class. * @@ -65,8 +73,8 @@ public static CacheDataDescriptionImpl decode(PersistentClass model) { model.isVersioned(), model.isVersioned() ? ( (VersionType) model.getVersion().getType() ).getComparator() - : null - ); + : null, + model.getIdentifierProperty().getType()); } /** @@ -82,8 +90,8 @@ public static CacheDataDescriptionImpl decode(Collection model) { model.getOwner().isVersioned(), model.getOwner().isVersioned() ? ( (VersionType) model.getOwner().getVersion().getType() ).getComparator() - : null - ); + : null, + model.getKey().getType()); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java index d70bca553ee4..15aa4c6ce43d 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java @@ -6,6 +6,7 @@ */ package org.hibernate.cache.internal; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; @@ -48,7 +49,7 @@ public static Object createEntityKey(Object id, EntityPersister persister, Sessi } public static Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { - return new OldNaturalIdCacheKey( naturalIdValues, persister, session ); + return new OldNaturalIdCacheKey( naturalIdValues, persister.getPropertyTypes(), persister.getNaturalIdentifierProperties(), persister.getRootEntityName(), session ); } public static Object getEntityId(Object cacheKey) { @@ -62,4 +63,36 @@ public static Object getCollectionId(Object cacheKey) { public static Object[] getNaturalIdValues(Object cacheKey) { return ((OldNaturalIdCacheKey) cacheKey).getNaturalIdValues(); } + + public static CacheKeysFactory INSTANCE = new CacheKeysFactory() { + @Override + public Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createCollectionKey(id, persister, factory, tenantIdentifier); + } + + @Override + public Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier); + } + + @Override + public Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session); + } + + @Override + public Object getEntityId(Object cacheKey) { + return DefaultCacheKeysFactory.getEntityId(cacheKey); + } + + @Override + public Object getCollectionId(Object cacheKey) { + return DefaultCacheKeysFactory.getCollectionId(cacheKey); + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + } + }; } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java index 8acf9de9f9b6..e0aa87e596b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java @@ -15,7 +15,6 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.internal.util.ValueHolder; import org.hibernate.internal.util.compare.EqualsHelper; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -39,24 +38,22 @@ public class OldNaturalIdCacheKey implements Serializable { /** * Construct a new key for a caching natural identifier resolutions into the second level cache. - * * @param naturalIdValues The naturalIdValues associated with the cached data - * @param persister The persister for the entity + * @param propertyTypes + * @param naturalIdPropertyIndexes * @param session The originating session */ public OldNaturalIdCacheKey( final Object[] naturalIdValues, - final EntityPersister persister, + Type[] propertyTypes, int[] naturalIdPropertyIndexes, final String entityName, final SessionImplementor session) { - this.entityName = persister.getRootEntityName(); + this.entityName = entityName; this.tenantId = session.getTenantIdentifier(); this.naturalIdValues = new Serializable[naturalIdValues.length]; final SessionFactoryImplementor factory = session.getFactory(); - final int[] naturalIdPropertyIndexes = persister.getNaturalIdentifierProperties(); - final Type[] propertyTypes = persister.getPropertyTypes(); final int prime = 31; int result = 1; @@ -91,7 +88,7 @@ private void initTransients() { public String initialize() { //Complex toString is needed as naturalIds for entities are not simply based on a single value like primary keys //the only same way to differentiate the keys is to included the disassembled values in the string. - final StringBuilder toStringBuilder = new StringBuilder( entityName ).append( "##NaturalId[" ); + final StringBuilder toStringBuilder = new StringBuilder().append( entityName ).append( "##NaturalId[" ); for ( int i = 0; i < naturalIdValues.length; i++ ) { toStringBuilder.append( naturalIdValues[i] ); if ( i + 1 < naturalIdValues.length ) { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java new file mode 100644 index 000000000000..831ccf8b9e7d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/SimpleCacheKeysFactory.java @@ -0,0 +1,54 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.cache.internal; + +import org.hibernate.cache.spi.CacheKeysFactory; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; + +/** + * Factory that does not fill in the entityName or role + * + * @author Radim Vansa <rvansa@redhat.com> + */ +public class SimpleCacheKeysFactory implements CacheKeysFactory { + + public static CacheKeysFactory INSTANCE = new SimpleCacheKeysFactory(); + + @Override + public Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return id; + } + + @Override + public Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { + return id; + } + + @Override + public Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { + // natural ids always need to be wrapped + return new OldNaturalIdCacheKey(naturalIdValues, persister.getPropertyTypes(), persister.getNaturalIdentifierProperties(), null, session); + } + + @Override + public Object getEntityId(Object cacheKey) { + return cacheKey; + } + + @Override + public Object getCollectionId(Object cacheKey) { + return cacheKey; + } + + @Override + public Object[] getNaturalIdValues(Object cacheKey) { + return ((OldNaturalIdCacheKey) cacheKey).getNaturalIdValues(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheDataDescription.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheDataDescription.java index 70b77582380e..eeecaaf9690b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheDataDescription.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheDataDescription.java @@ -8,6 +8,8 @@ import java.util.Comparator; +import org.hibernate.type.Type; + /** * Describes attributes regarding the type of data to be cached. * @@ -37,4 +39,10 @@ public interface CacheDataDescription { * @return The comparator for versions, or {@code null} */ public Comparator getVersionComparator(); + + /** + * @return Type of the key that will be used as the key in the cache, or {@code null} if the natural comparison + * ({@link Object#hashCode()} and {@link Object#equals(Object)} methods should be used. + */ + Type getKeyType(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java new file mode 100644 index 000000000000..d9ce86fce57f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKeysFactory.java @@ -0,0 +1,29 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.cache.spi; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.EntityPersister; + +/** + * @author Radim Vansa <rvansa@redhat.com> + */ +public interface CacheKeysFactory { + Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier); + + Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier); + + Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session); + + Object getEntityId(Object cacheKey); + + Object getCollectionId(Object cacheKey); + + Object[] getNaturalIdValues(Object cacheKey); +} diff --git a/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java b/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java index 9143c57f202e..8cc1ef75c2f3 100644 --- a/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java @@ -62,7 +62,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable { }); final OldNaturalIdCacheKey key = (OldNaturalIdCacheKey) DefaultCacheKeysFactory.createNaturalIdKey( new Object[] {"a", "b", "c"}, entityPersister, sessionImplementor ); - + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(key); diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java index b88131817fed..75fec1936c94 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java @@ -6,6 +6,21 @@ */ package org.hibernate.cache.infinispan; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.hibernate.MultiTenancyStrategy; import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.collection.CollectionRegionImpl; @@ -19,7 +34,10 @@ import org.hibernate.cache.infinispan.tm.HibernateTransactionManagerLookup; import org.hibernate.cache.infinispan.util.CacheCommandFactory; import org.hibernate.cache.infinispan.util.Caches; +import org.hibernate.cache.internal.DefaultCacheKeysFactory; +import org.hibernate.cache.internal.SimpleCacheKeysFactory; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.NaturalIdRegion; @@ -46,20 +64,6 @@ import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.TimeUnit; - /** * A {@link RegionFactory} for Infinispan-backed cache * regions. @@ -215,6 +219,7 @@ public class InfinispanRegionFactory implements RegionFactory { private org.infinispan.transaction.lookup.TransactionManagerLookup transactionManagerlookup; private List regionNames = new ArrayList(); + private SessionFactoryOptions settings; /** * Create a new instance using the default configuration. @@ -239,8 +244,8 @@ public CollectionRegion buildCollectionRegion( if ( log.isDebugEnabled() ) { log.debug( "Building collection cache region [" + regionName + "]" ); } - final AdvancedCache cache = getCache( regionName, COLLECTION_KEY, properties ); - final CollectionRegionImpl region = new CollectionRegionImpl( cache, regionName, metadata, this ); + final AdvancedCache cache = getCache( regionName, COLLECTION_KEY, properties, metadata); + final CollectionRegionImpl region = new CollectionRegionImpl( cache, regionName, metadata, this, buildCacheKeysFactory() ); startRegion( region, regionName ); return region; } @@ -249,10 +254,10 @@ public CollectionRegion buildCollectionRegion( public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException { if ( log.isDebugEnabled() ) { - log.debugf( "Building entity cache region [%s] (mutable=%s, versioned=%s)", regionName, metadata.isMutable(), metadata.isVersioned()); + log.debugf("Building entity cache region [%s] (mutable=%s, versioned=%s)", regionName, metadata.isMutable(), metadata.isVersioned()); } - final AdvancedCache cache = getCache( regionName, metadata.isMutable() ? ENTITY_KEY : IMMUTABLE_ENTITY_KEY, properties ); - final EntityRegionImpl region = new EntityRegionImpl( cache, regionName, metadata, this ); + final AdvancedCache cache = getCache( regionName, metadata.isMutable() ? ENTITY_KEY : IMMUTABLE_ENTITY_KEY, properties, metadata ); + final EntityRegionImpl region = new EntityRegionImpl( cache, regionName, metadata, this, buildCacheKeysFactory() ); startRegion( region, regionName ); return region; } @@ -261,10 +266,10 @@ public EntityRegion buildEntityRegion(String regionName, Properties properties, public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException { if ( log.isDebugEnabled() ) { - log.debug( "Building natural id cache region [" + regionName + "]" ); + log.debug("Building natural id cache region [" + regionName + "]"); } - final AdvancedCache cache = getCache( regionName, NATURAL_ID_KEY, properties ); - final NaturalIdRegionImpl region = new NaturalIdRegionImpl( cache, regionName, metadata, this ); + final AdvancedCache cache = getCache( regionName, NATURAL_ID_KEY, properties, metadata); + final NaturalIdRegionImpl region = new NaturalIdRegionImpl( cache, regionName, metadata, this, buildCacheKeysFactory()); startRegion( region, regionName ); return region; } @@ -281,7 +286,7 @@ public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties cacheName = regionName; } - final AdvancedCache cache = getCache( cacheName, QUERY_KEY, properties ); + final AdvancedCache cache = getCache( cacheName, QUERY_KEY, properties, null); final QueryResultsRegionImpl region = new QueryResultsRegionImpl( cache, regionName, this ); startRegion( region, regionName ); return region; @@ -293,7 +298,7 @@ public TimestampsRegion buildTimestampsRegion(String regionName, Properties prop if ( log.isDebugEnabled() ) { log.debug( "Building timestamps cache region [" + regionName + "]" ); } - final AdvancedCache cache = getCache( regionName, TIMESTAMPS_KEY, properties ); + final AdvancedCache cache = getCache( regionName, TIMESTAMPS_KEY, properties, null); final TimestampsRegionImpl region = createTimestampsRegion( cache, regionName ); startRegion( region, regionName ); return region; @@ -301,7 +306,7 @@ public TimestampsRegion buildTimestampsRegion(String regionName, Properties prop protected TimestampsRegionImpl createTimestampsRegion( AdvancedCache cache, String regionName) { - if ( Caches.isClustered( cache ) ) { + if ( Caches.isClustered(cache) ) { return new ClusteredTimestampsRegionImpl( cache, regionName, this ); } else { @@ -309,6 +314,14 @@ protected TimestampsRegionImpl createTimestampsRegion( } } + private CacheKeysFactory buildCacheKeysFactory() { + if (settings.getMultiTenancyStrategy() != MultiTenancyStrategy.NONE) { + return DefaultCacheKeysFactory.INSTANCE; + } else { + return SimpleCacheKeysFactory.INSTANCE; + } + } + @Override public boolean isMinimalPutsEnabledByDefault() { return true; @@ -338,6 +351,7 @@ public void start(SessionFactoryOptions settings, Properties properties) throws try { transactionManagerlookup = createTransactionManagerLookup( settings, properties ); manager = createCacheManager( properties ); + this.settings = settings; initGenericDataTypeOverrides(); final Enumeration keys = properties.propertyNames(); while ( keys.hasMoreElements() ) { @@ -543,7 +557,7 @@ private void defineGenericDataTypeCacheConfigurations(Properties properties) { } } - private AdvancedCache getCache(String regionName, String typeKey, Properties properties) { + private AdvancedCache getCache(String regionName, String typeKey, Properties properties, CacheDataDescription metadata) { TypeOverrides regionOverride = typeOverrides.get( regionName ); if ( !definedConfigurations.contains( regionName ) ) { final String templateCacheName; @@ -577,6 +591,13 @@ private AdvancedCache getCache(String regionName, String typeKey, Properties pro // Apply overrides typeOverrides.get( typeKey ).applyTo( builder ); } + // with multi-tenancy the keys will be wrapped + if (settings.getMultiTenancyStrategy() == MultiTenancyStrategy.NONE) { + // the keys may not define hashCode/equals correctly (e.g. arrays) + if (metadata != null && metadata.getKeyType() != null) { + builder.dataContainer().keyEquivalence(new TypeEquivalance(metadata.getKeyType())); + } + } // Configure transaction manager configureTransactionManager( builder, templateCacheName, properties ); // Define configuration diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/TypeEquivalance.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/TypeEquivalance.java new file mode 100644 index 000000000000..82bd5639fc98 --- /dev/null +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/TypeEquivalance.java @@ -0,0 +1,40 @@ +package org.hibernate.cache.infinispan; + +import org.hibernate.type.Type; +import org.infinispan.commons.equivalence.Equivalence; + +/** + * @author Radim Vansa <rvansa@redhat.com> + */ +public class TypeEquivalance implements Equivalence { + private final Type type; + + public TypeEquivalance(Type type) { + this.type = type; + } + + @Override + public int hashCode(Object o) { + return type.getHashCode(o); + } + + @Override + public boolean equals(Object x, Object y) { + return type.isEqual(x, y); + } + + @Override + public String toString(Object o) { + return String.valueOf(o); + } + + @Override + public boolean isComparable(Object o) { + return true; // cannot guess from the type + } + + @Override + public int compare(Object x, Object y) { + return type.compare(x, y); + } +} diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java index 9ab7ac06536d..69edd85bbf15 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java @@ -6,6 +6,9 @@ */ package org.hibernate.cache.infinispan.access; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -15,14 +18,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; - import org.infinispan.AdvancedCache; +import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.manager.EmbeddedCacheManager; /** @@ -130,27 +131,37 @@ public PutFromLoadValidator(AdvancedCache cache) { public PutFromLoadValidator( AdvancedCache cache, long nakedPutInvalidationPeriod) { - this( - cache.getCacheManager(), cache.getTransactionManager(), + this(cache, cache.getCacheManager(), cache.getTransactionManager(), nakedPutInvalidationPeriod ); } /** * Creates a new put from load validator instance. - * - * @param cacheManager where to find a cache to store pending put information - * @param tm transaction manager - * @param nakedPutInvalidationPeriod Period (in ms) after a removal during which a call to - * {@link #acquirePutFromLoadLock(Object)} that hasn't been - * {@link #registerPendingPut(Object) pre-registered} (aka a "naked put") - * will return false. - */ - public PutFromLoadValidator( + * + * @param cache Cache instance on which to store pending put information. + * @param cacheManager where to find a cache to store pending put information + * @param tm transaction manager + * @param nakedPutInvalidationPeriod Period (in ms) after a removal during which a call to + * {@link #acquirePutFromLoadLock(Object)} that hasn't been + * {@link #registerPendingPut(Object) pre-registered} (aka a "naked put") + * will return false. + */ + public PutFromLoadValidator(AdvancedCache cache, EmbeddedCacheManager cacheManager, TransactionManager tm, long nakedPutInvalidationPeriod) { - this.pendingPuts = cacheManager - .getCache( InfinispanRegionFactory.PENDING_PUTS_CACHE_NAME ); + + Configuration cacheConfiguration = cache.getCacheConfiguration(); + Configuration pendingPutsConfiguration = cacheManager.getCacheConfiguration(InfinispanRegionFactory.PENDING_PUTS_CACHE_NAME); + ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); + if (pendingPutsConfiguration != null) { + configurationBuilder.read(pendingPutsConfiguration); + } + configurationBuilder.dataContainer().keyEquivalence(cacheConfiguration.dataContainer().keyEquivalence()); + String pendingPutsName = cache.getName() + "-" + InfinispanRegionFactory.PENDING_PUTS_CACHE_NAME; + cacheManager.defineConfiguration(pendingPutsName, configurationBuilder.build()); + + this.pendingPuts = cacheManager.getCache(pendingPutsName); this.transactionManager = tm; this.nakedPutInvalidationPeriod = nakedPutInvalidationPeriod; } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java index 0150e7954a67..869c6bef24be 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java @@ -10,11 +10,11 @@ import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; - import org.infinispan.AdvancedCache; /** @@ -33,11 +33,12 @@ public class CollectionRegionImpl extends BaseTransactionalDataRegion implements * @param name of collection type * @param metadata for the collection type * @param factory for the region + * @param cacheKeysFactory factory for cache keys */ public CollectionRegionImpl( AdvancedCache cache, String name, - CacheDataDescription metadata, RegionFactory factory) { - super( cache, name, metadata, factory ); + CacheDataDescription metadata, RegionFactory factory, CacheKeysFactory cacheKeysFactory) { + super( cache, name, metadata, factory, cacheKeysFactory ); } @Override diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java index a72a093c015f..3c49f911535b 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java @@ -8,7 +8,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; -import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -82,12 +81,12 @@ 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); + return region.getCacheKeysFactory().createCollectionKey(id, persister, factory, tenantIdentifier); } @Override public Object getCacheKeyId(Object cacheKey) { - return DefaultCacheKeysFactory.getCollectionId(cacheKey); + return region.getCacheKeysFactory().getCollectionId(cacheKey); } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java index f81a642211d9..1cc5215a5455 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java @@ -10,6 +10,7 @@ import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.access.AccessType; @@ -33,11 +34,12 @@ public class EntityRegionImpl extends BaseTransactionalDataRegion implements Ent * @param name of entity type * @param metadata for the entity type * @param factory for the region + * @param cacheKeysFactory factory for cache keys */ public EntityRegionImpl( AdvancedCache cache, String name, - CacheDataDescription metadata, RegionFactory factory) { - super( cache, name, metadata, factory ); + CacheDataDescription metadata, RegionFactory factory, CacheKeysFactory cacheKeysFactory) { + super( cache, name, metadata, factory, cacheKeysFactory); } @Override @@ -60,5 +62,4 @@ public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) thr public PutFromLoadValidator getPutFromLoadValidator() { return new PutFromLoadValidator( cache ); } - } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java index 15f408144d93..e24e5e4147a8 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java @@ -8,7 +8,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; -import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -100,11 +99,11 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje @Override public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) { - return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier); + return region.getCacheKeysFactory().createEntityKey(id, persister, factory, tenantIdentifier); } @Override public Object getCacheKeyId(Object cacheKey) { - return DefaultCacheKeysFactory.getEntityId(cacheKey); + return region.getCacheKeysFactory().getEntityId(cacheKey); } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java index e9746b4d02c9..06a81dba02ef 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseTransactionalDataRegion.java @@ -7,6 +7,7 @@ package org.hibernate.cache.infinispan.impl; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; @@ -23,6 +24,7 @@ public abstract class BaseTransactionalDataRegion extends BaseRegion implements TransactionalDataRegion { private final CacheDataDescription metadata; + private final CacheKeysFactory cacheKeysFactory; /** * Base transactional region constructor @@ -31,12 +33,14 @@ public abstract class BaseTransactionalDataRegion * @param name of the transactional region * @param metadata for the transactional region * @param factory for the transactional region + * @param cacheKeysFactory factory for cache keys */ public BaseTransactionalDataRegion( AdvancedCache cache, String name, - CacheDataDescription metadata, RegionFactory factory) { - super( cache, name, factory ); + CacheDataDescription metadata, RegionFactory factory, CacheKeysFactory cacheKeysFactory) { + super( cache, name, factory); this.metadata = metadata; + this.cacheKeysFactory = cacheKeysFactory; } @Override @@ -44,4 +48,7 @@ public CacheDataDescription getCacheDataDescription() { return metadata; } + public CacheKeysFactory getCacheKeysFactory() { + return cacheKeysFactory; + } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java index 89c1f5e19bcd..3c7b6d82f456 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/NaturalIdRegionImpl.java @@ -10,11 +10,11 @@ import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion; import org.hibernate.cache.spi.CacheDataDescription; +import org.hibernate.cache.spi.CacheKeysFactory; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; - import org.infinispan.AdvancedCache; /** @@ -33,11 +33,12 @@ public class NaturalIdRegionImpl extends BaseTransactionalDataRegion * @param name of natural id region * @param metadata for the natural id region * @param factory for the natural id region + * @param cacheKeysFactory factory for cache keys */ public NaturalIdRegionImpl( AdvancedCache cache, String name, - CacheDataDescription metadata, RegionFactory factory) { - super( cache, name, metadata, factory ); + CacheDataDescription metadata, RegionFactory factory, CacheKeysFactory cacheKeysFactory) { + super( cache, name, metadata, factory, cacheKeysFactory ); } @Override diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/TransactionalAccess.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/TransactionalAccess.java index 8817b39e3489..41706f6a3a79 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/TransactionalAccess.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/naturalid/TransactionalAccess.java @@ -8,7 +8,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.access.TransactionalAccessDelegate; -import org.hibernate.cache.internal.DefaultCacheKeysFactory; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; @@ -108,11 +107,11 @@ public boolean afterUpdate(Object key, Object value, SoftLock lock) throws Cache @Override public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) { - return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session ); + return region.getCacheKeysFactory().createNaturalIdKey(naturalIdValues, persister, session); } @Override public Object[] getNaturalIdValues(Object cacheKey) { - return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey); + return region.getCacheKeysFactory().getNaturalIdValues(cacheKey); } } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java index cbbf0b14491f..a5c2eb3f968d 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/query/QueryResultsRegionImpl.java @@ -13,7 +13,6 @@ import org.hibernate.cache.infinispan.util.Caches; import org.hibernate.cache.spi.QueryResultsRegion; import org.hibernate.cache.spi.RegionFactory; - import org.infinispan.AdvancedCache; import org.infinispan.context.Flag; @@ -38,7 +37,7 @@ public class QueryResultsRegionImpl extends BaseTransactionalDataRegion implemen * @param factory for the query region */ public QueryResultsRegionImpl(AdvancedCache cache, String name, RegionFactory factory) { - super( cache, name, null, factory ); + super( cache, name, null, factory, null ); // If Infinispan is using INVALIDATION for query cache, we don't want to propagate changes. // We use the Timestamps cache to manage invalidation final boolean localOnly = Caches.isInvalidationCache( cache ); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java index b08b0718e86e..d8b84bf9fe19 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractEntityCollectionRegionTestCase.java @@ -11,10 +11,12 @@ import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; +import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; import org.hibernate.cache.spi.access.AccessType; +import org.hibernate.internal.util.compare.ComparableComparator; import org.hibernate.test.cache.infinispan.util.CacheTestUtil; import org.junit.Test; @@ -29,6 +31,8 @@ * @since 3.5 */ public abstract class AbstractEntityCollectionRegionTestCase extends AbstractRegionImplTestCase { + protected static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, ComparableComparator.INSTANCE, null); + @Test public void testSupportedAccessTypes() throws Exception { supportedAccessTypeTest(); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java index 2daf5ad2e0d9..57c3198b7fe9 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/AbstractRegionImplTestCase.java @@ -32,7 +32,7 @@ public abstract class AbstractRegionImplTestCase extends AbstractNonFunctionalTe protected abstract void removeFromRegion(Region region, Object key); protected CacheDataDescription getCacheDataDescription() { - return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE); + return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE, null); } } diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java index f58a4e0c3738..05655a138b29 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/InfinispanRegionFactoryTestCase.java @@ -6,6 +6,12 @@ */ package org.hibernate.test.cache.infinispan; +import javax.transaction.TransactionManager; +import java.util.Properties; + +import org.hibernate.boot.internal.SessionFactoryBuilderImpl; +import org.hibernate.boot.internal.SessionFactoryOptionsImpl; +import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; @@ -20,6 +26,7 @@ import org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform; import org.hibernate.engine.transaction.jta.platform.internal.JBossStandAloneJtaPlatform; import org.hibernate.test.cache.infinispan.functional.SingleNodeTestCase; +import org.hibernate.test.cache.infinispan.util.CacheTestUtil; import org.hibernate.testing.ServiceRegistryBuilder; import org.infinispan.AdvancedCache; import org.infinispan.configuration.cache.CacheMode; @@ -33,10 +40,12 @@ import org.infinispan.transaction.TransactionMode; import org.junit.Test; -import javax.transaction.TransactionManager; -import java.util.Properties; - -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * InfinispanRegionFactoryTestCase. @@ -45,8 +54,13 @@ * @since 3.5 */ public class InfinispanRegionFactoryTestCase { - private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); - private static CacheDataDescription IMMUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(false, false, null); + private static final CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null, null); + private static final CacheDataDescription IMMUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(false, false, null, null); + + private static final StandardServiceRegistry REGISTRY + = CacheTestUtil.buildBaselineStandardServiceRegistryBuilder("test", InfinispanRegionFactory.class, true, false).build(); + private static final SessionFactoryOptions SETTINGS = new SessionFactoryOptionsImpl( + new SessionFactoryBuilderImpl.SessionFactoryOptionsStateStandardImpl( REGISTRY )); @Test public void testConfigurationProcessing() { @@ -553,6 +567,10 @@ private InfinispanRegionFactory createRegionFactory(Properties p) { } private InfinispanRegionFactory createRegionFactory(final EmbeddedCacheManager manager, Properties p) { + return createRegionFactory(manager, p, SETTINGS); + } + + private InfinispanRegionFactory createRegionFactory(final EmbeddedCacheManager manager, Properties p, SessionFactoryOptions settings) { final InfinispanRegionFactory factory = new SingleNodeTestCase.TestInfinispanRegionFactory() { @Override @@ -577,7 +595,7 @@ protected EmbeddedCacheManager createCacheManager(Properties properties) throws }; - factory.start(null, p); + factory.start(settings, p); return factory; } diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java index de2b93b3b24f..066b1184707f 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java @@ -6,6 +6,7 @@ */ package org.hibernate.test.cache.infinispan.access; +import javax.transaction.TransactionManager; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; @@ -15,20 +16,18 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import javax.transaction.TransactionManager; import org.hibernate.cache.infinispan.access.PutFromLoadValidator; - import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - +import org.infinispan.AdvancedCache; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.CacheManagerCallable; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import static org.infinispan.test.TestingUtil.withCacheManager; import static org.junit.Assert.assertEquals; @@ -84,7 +83,7 @@ private void nakedPutTest(final boolean transactional) throws Exception { @Override public void call() { try { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); if (transactional) { @@ -119,7 +118,7 @@ private void registeredPutTest(final boolean transactional) throws Exception { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); try { @@ -166,7 +165,7 @@ private void nakedPutAfterRemovalTest(final boolean transactional, TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); if (removeRegion) { @@ -218,7 +217,7 @@ private void registeredPutAfterRemovalTest(final boolean transactional, TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); if (removeRegion) { @@ -272,7 +271,7 @@ private void registeredPutWithInterveningRemovalTest( TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new PutFromLoadValidator(cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); try { @@ -325,7 +324,7 @@ private void delayedNakedPutAfterRemovalTest( TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new TestValidator(cm, + PutFromLoadValidator testee = new TestValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, 100); if (removeRegion) { testee.invalidateRegion(); @@ -368,7 +367,7 @@ private void multipleRegistrationtest(final boolean transactional) throws Except TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - final PutFromLoadValidator testee = new PutFromLoadValidator(cm, + final PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); @@ -440,8 +439,8 @@ private void invalidationBlocksForInProgressPutTest(final boolean keyOnly) throw TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - final PutFromLoadValidator testee = new PutFromLoadValidator( - cm, null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); + final PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), + cm, null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); final CountDownLatch removeLatch = new CountDownLatch(1); final CountDownLatch pferLatch = new CountDownLatch(1); final AtomicReference cache = new AtomicReference("INITIAL"); @@ -503,10 +502,10 @@ public Void call() throws Exception { private static class TestValidator extends PutFromLoadValidator { - protected TestValidator(EmbeddedCacheManager cm, + protected TestValidator(AdvancedCache cache, EmbeddedCacheManager cm, TransactionManager transactionManager, long nakedPutInvalidationPeriod) { - super(cm, transactionManager, nakedPutInvalidationPeriod); + super(cache, cm, transactionManager, nakedPutInvalidationPeriod); } @Override diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java index 1d85372e9952..af8aedf97b1c 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/AbstractCollectionRegionAccessStrategyTestCase.java @@ -115,7 +115,7 @@ protected static StandardServiceRegistryBuilder createStandardServiceRegistryBui } protected CacheDataDescription getCacheDataDescription() { - return new CacheDataDescriptionImpl( true, true, ComparableComparator.INSTANCE ); + return new CacheDataDescriptionImpl( true, true, ComparableComparator.INSTANCE, null); } @After @@ -152,7 +152,7 @@ public void testPutFromLoadRemoveDoesNotProduceStaleData() throws Exception { withCacheManager(new CacheManagerCallable(TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator validator = new PutFromLoadValidator(cm, + PutFromLoadValidator validator = new PutFromLoadValidator(remoteCollectionRegion.getCache(), cm, remoteTm, 20000) { @Override public boolean acquirePutFromLoadLock(Object key) { diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java index a26b2581cde8..6b96a699996e 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java @@ -10,7 +10,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; -import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.CollectionRegion; import org.hibernate.cache.spi.Region; @@ -29,9 +28,6 @@ * @author Galder Zamarreño */ public class CollectionRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { - - private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); - @Override protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties properties) { CollectionRegion region = regionFactory.buildCollectionRegion("test", properties, MUTABLE_NON_VERSIONED); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java index 61503cb1ff4a..07e594845262 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/TransactionalExtraAPITestCase.java @@ -8,9 +8,12 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cache.infinispan.InfinispanRegionFactory; +import org.hibernate.cache.internal.CacheDataDescriptionImpl; +import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; +import org.hibernate.internal.util.compare.ComparableComparator; import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase; import org.hibernate.test.cache.infinispan.NodeEnvironment; import org.hibernate.test.cache.infinispan.util.CacheTestUtil; @@ -31,8 +34,8 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase public static final String REGION_NAME = "test/com.foo.test"; public static final Object KEY = TestingKeyFactory.generateCollectionCacheKey( "KEY" ); - public static final String VALUE1 = "VALUE1"; - public static final String VALUE2 = "VALUE2"; + public static final CacheDataDescription CACHE_DATA_DESCRIPTION + = new CacheDataDescriptionImpl(false, false, ComparableComparator.INSTANCE, null); private NodeEnvironment environment; private static CollectionRegionAccessStrategy accessStrategy; @@ -45,7 +48,7 @@ public final void prepareLocalAccessStrategy() throws Exception { // Sleep a bit to avoid concurrent FLUSH problem avoidConcurrentFlush(); - accessStrategy = environment.getCollectionRegion( REGION_NAME, null ).buildAccessStrategy( getAccessType() ); + accessStrategy = environment.getCollectionRegion( REGION_NAME, CACHE_DATA_DESCRIPTION).buildAccessStrategy( getAccessType() ); } protected StandardServiceRegistryBuilder createStandardServiceRegistryBuilder() { diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java index da336ff0d976..0eab81e6ba42 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java @@ -115,7 +115,7 @@ protected static StandardServiceRegistryBuilder createStandardServiceRegistryBui } protected CacheDataDescription getCacheDataDescription() { - return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE); + return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE, null); } @After diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java index 2752a415073a..645bc5a2502e 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java @@ -10,7 +10,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.InfinispanRegionFactory; -import org.hibernate.cache.internal.CacheDataDescriptionImpl; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.Region; @@ -30,8 +29,6 @@ */ public class EntityRegionImplTestCase extends AbstractEntityCollectionRegionTestCase { - private static CacheDataDescription MUTABLE_NON_VERSIONED = new CacheDataDescriptionImpl(true, false, null); - @Override protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties properties) { EntityRegion region = regionFactory.buildEntityRegion("test", properties, MUTABLE_NON_VERSIONED); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java index 61fb89aa3e1b..18ca82ebd668 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/TransactionalExtraAPITestCase.java @@ -12,6 +12,7 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.SoftLock; +import org.hibernate.internal.util.compare.ComparableComparator; import org.hibernate.test.cache.infinispan.AbstractNonFunctionalTestCase; import org.hibernate.test.cache.infinispan.NodeEnvironment; import org.hibernate.test.cache.infinispan.util.CacheTestUtil; @@ -38,6 +39,8 @@ public class TransactionalExtraAPITestCase extends AbstractNonFunctionalTestCase public static final Object KEY = TestingKeyFactory.generateEntityCacheKey( "KEY" ); public static final String VALUE1 = "VALUE1"; public static final String VALUE2 = "VALUE2"; + protected static final CacheDataDescriptionImpl CACHE_DATA_DESCRIPTION + = new CacheDataDescriptionImpl(true, false, ComparableComparator.INSTANCE, null); private NodeEnvironment environment; private EntityRegionAccessStrategy accessStrategy; @@ -50,7 +53,7 @@ public final void prepareLocalAccessStrategy() throws Exception { // Sleep a bit to avoid concurrent FLUSH problem avoidConcurrentFlush(); - accessStrategy = environment.getEntityRegion( REGION_NAME, new CacheDataDescriptionImpl(true, false, null)).buildAccessStrategy( getAccessType() ); + accessStrategy = environment.getEntityRegion( REGION_NAME, CACHE_DATA_DESCRIPTION).buildAccessStrategy( getAccessType() ); } protected StandardServiceRegistryBuilder createStandardServiceRegistryBuilder() { diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/EqualityTest.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/EqualityTest.java new file mode 100644 index 000000000000..6046c331bcf0 --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/EqualityTest.java @@ -0,0 +1,77 @@ +package org.hibernate.test.cache.infinispan.functional; + +import java.util.concurrent.Callable; + +import org.hibernate.Session; +import org.hibernate.stat.Statistics; +import org.junit.Test; + +import static org.infinispan.test.TestingUtil.withTx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * Persons should be correctly indexed since we can use Type for comparison + * + * @author Radim Vansa <rvansa@redhat.com> + */ +public class EqualityTest extends SingleNodeTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Person.class }; + } + + @Test + public void testEqualityFromType() throws Exception { + Person john = new Person("John", "Black", 26); + Person peter = new Person("Peter", "White", 32); + + withTx(tm, new Callable() { + @Override + public Void call() throws Exception { + Session session = openSession(); + session.getTransaction().begin(); + session.persist(john); + session.persist(peter); + session.getTransaction().commit(); + session.close(); + return null; + } + }); + + Statistics statistics = sessionFactory().getStatistics(); + statistics.clear(); + + for (int i = 0; i < 5; ++i) { + withTx(tm, new Callable() { + @Override + public Void call() throws Exception { + Session session = openSession(); + session.getTransaction().begin(); + Person p1 = session.get(Person.class, john.name); + assertPersonEquals(john, p1); + Person p2 = session.get(Person.class, peter.name); + assertPersonEquals(peter, p2); + Person p3 = session.get(Person.class, new Name("Foo", "Bar")); + assertNull(p3); + session.getTransaction().commit(); + session.close(); + return null; + } + }); + } + + assertTrue(statistics.getSecondLevelCacheHitCount() > 0); + assertTrue(statistics.getSecondLevelCacheMissCount() > 0); + } + + private static void assertPersonEquals(Person expected, Person person) { + assertNotNull(person); + assertNotNull(person.getName()); + assertEquals(expected.getName().getFirstName(), person.getName().getFirstName()); + assertEquals(expected.getName().getLastName(), person.getName().getLastName()); + assertEquals(expected.getAge(), person.getAge()); + } +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java new file mode 100644 index 000000000000..e11f4c460ec5 --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java @@ -0,0 +1,115 @@ +package org.hibernate.test.cache.infinispan.functional; + +import java.util.concurrent.Callable; + +import org.hibernate.MultiTenancyStrategy; +import org.hibernate.Session; +import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cache.infinispan.entity.EntityRegionImpl; +import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider; +import org.hibernate.testing.env.ConnectionProviderBuilder; +import org.infinispan.commons.util.CloseableIteratorSet; +import org.infinispan.context.Flag; +import org.junit.Test; + +import static org.infinispan.test.TestingUtil.withTx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Radim Vansa <rvansa@redhat.com> + */ +public class MultiTenancyTestCase extends SingleNodeTestCase { + + private static final String DB1 = "db1"; + private static final String DB2 = "db2"; + private final ConnectionProvider db1 = ConnectionProviderBuilder.buildConnectionProvider(DB1); + private final ConnectionProvider db2 = ConnectionProviderBuilder.buildConnectionProvider(DB2); + + @Override + protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) { + super.configureStandardServiceRegistryBuilder(ssrb); + ssrb.addService(MultiTenantConnectionProvider.class, new AbstractMultiTenantConnectionProvider() { + + @Override + protected ConnectionProvider getAnyConnectionProvider() { + return db1; + } + + @Override + protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) { + if (DB1.equals(tenantIdentifier)) return db1; + if (DB2.equals(tenantIdentifier)) return db2; + throw new IllegalArgumentException(); + } + }); + } + + @Override + protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) { + super.configureSessionFactoryBuilder(sfb); + sfb.applyMultiTenancyStrategy(MultiTenancyStrategy.DATABASE); + } + + @Override + protected void cleanupTest() throws Exception { + db1.getConnection().close(); + db2.getConnection().close(); + } + + @Test + public void testMultiTenancy() throws Exception { + final Item item = new Item("my item", "description" ); + + long id = withTx(tm, new Callable() { + @Override + public Long call() throws Exception { + Session s = sessionFactory().withOptions().tenantIdentifier(DB1).openSession(); + s.getTransaction().begin(); + s.persist(item); + s.getTransaction().commit(); + s.close(); + return item.getId(); + } + }); + for (int i = 0; i < 5; ++i) { // make sure we get something cached + withTx(tm, new Callable() { + @Override + public Void call() throws Exception { + Session s = sessionFactory().withOptions().tenantIdentifier(DB1).openSession(); + s.getTransaction().begin(); + Item item2 = s.get(Item.class, id); + s.getTransaction().commit(); + s.close(); + assertNotNull(item2); + assertEquals(item.getName(), item2.getName()); + return null; + } + }); + + } + // The table ITEMS is not created in DB2 - we would get just an exception +// for (int i = 0; i < 5; ++i) { // make sure we get something cached +// withTx(tm, new Callable() { +// @Override +// public Void call() throws Exception { +// Session s = sessionFactory().withOptions().tenantIdentifier(DB2).openSession(); +// s.getTransaction().begin(); +// Item item2 = s.get(Item.class, id); +// s.getTransaction().commit(); +// s.close(); +// assertNull(item2); +// return null; +// } +// }); +// } + EntityRegionImpl region = (EntityRegionImpl) sessionFactory().getSecondLevelCacheRegion(Item.class.getName()); + CloseableIteratorSet keySet = region.getCache().withFlags(Flag.CACHE_MODE_LOCAL).keySet(); + assertEquals(1, keySet.size()); + assertEquals("OldCacheKeyImplementation", keySet.iterator().next().getClass().getSimpleName()); + } + +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Name.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Name.java new file mode 100644 index 000000000000..efc9996aca85 --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Name.java @@ -0,0 +1,48 @@ +package org.hibernate.test.cache.infinispan.functional; + +import javax.persistence.Embeddable; +import java.io.Serializable; + +/** + * Test class with incorrectly defined equals and hashCode. + * + * @author Radim Vansa <rvansa@redhat.com> + */ +@Embeddable +public class Name implements Serializable { + String firstName; + String lastName; + + public Name() {} + + public Name(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public boolean equals(Object obj) { + return false; + } +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/NoTenancyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/NoTenancyTestCase.java new file mode 100644 index 000000000000..e79541c36e74 --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/NoTenancyTestCase.java @@ -0,0 +1,56 @@ +package org.hibernate.test.cache.infinispan.functional; + +import java.util.concurrent.Callable; + +import org.hibernate.Session; +import org.hibernate.cache.infinispan.entity.EntityRegionImpl; +import org.infinispan.commons.util.CloseableIteratorSet; +import org.infinispan.context.Flag; +import org.junit.Test; + +import static org.infinispan.test.TestingUtil.withTx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Radim Vansa <rvansa@redhat.com> + */ +public class NoTenancyTestCase extends SingleNodeTestCase { + @Test + public void testNoTenancy() throws Exception { + final Item item = new Item("my item", "description" ); + + long id = withTx(tm, new Callable() { + @Override + public Long call() throws Exception { + Session s = openSession(); + s.getTransaction().begin(); + s.persist(item); + s.getTransaction().commit(); + s.close(); + return item.getId(); + } + }); + for (int i = 0; i < 5; ++i) { // make sure we get something cached + withTx(tm, new Callable() { + @Override + public Void call() throws Exception { + Session s = openSession(); + s.getTransaction().begin(); + Item item2 = s.get(Item.class, id); + s.getTransaction().commit(); + s.close(); + assertNotNull(item2); + assertEquals(item.getName(), item2.getName()); + return null; + } + }); + + } + EntityRegionImpl region = (EntityRegionImpl) sessionFactory().getSecondLevelCacheRegion(Item.class.getName()); + CloseableIteratorSet keySet = region.getCache().withFlags(Flag.CACHE_MODE_LOCAL).keySet(); + assertEquals(1, keySet.size()); + assertEquals(sessionFactory().getClassMetadata(Item.class).getIdentifierType().getReturnedClass(), keySet.iterator().next().getClass()); + } + +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Person.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Person.java new file mode 100644 index 000000000000..222525c4fff5 --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/Person.java @@ -0,0 +1,41 @@ +package org.hibernate.test.cache.infinispan.functional; + +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import java.io.Serializable; + +/** + * Test class using EmbeddedId + * + * @author Radim Vansa <rvansa@redhat.com> + */ +@Entity +public class Person implements Serializable { + @EmbeddedId + Name name; + + int age; + + public Person() {} + + public Person(String firstName, String lastName, int age) { + name = new Name(firstName, lastName); + this.age = age; + } + + public Name getName() { + return name; + } + + public void setName(Name name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java index 2a8ba6baf07b..782e14491404 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java @@ -343,7 +343,7 @@ public boolean isEmpty() { public void nodeVisited(CacheEntryVisitedEvent event) { log.debug( event.toString() ); if ( !event.isPre() ) { - String key = String.valueOf(event.getKey()); + String key = event.getCache().getName() + "#" + event.getKey(); log.debug( "MyListener[" + name + "] - Visiting key " + key ); // String name = fqn.toString(); String token = ".functional."; @@ -351,7 +351,7 @@ public void nodeVisited(CacheEntryVisitedEvent event) { if ( index > -1 ) { index += token.length(); key = key.substring( index ); - log.debug( "MyListener[" + name + "] - recording visit to " + key ); + log.debug( "MyListener[" + this.name + "] - recording visit to " + key ); visited.add( key ); } } From ad30c90f0fba94b54537b80f2e20501c3d0d552d Mon Sep 17 00:00:00 2001 From: Radim Vansa Date: Fri, 19 Jun 2015 16:36:45 +0200 Subject: [PATCH 5/7] Fixed not committed connection --- .../infinispan/functional/MultiTenancyTestCase.java | 7 +++++-- .../cache/infinispan/tm/XaConnectionProvider.java | 13 +++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java index e11f4c460ec5..c2f2eab6d14f 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/MultiTenancyTestCase.java @@ -10,6 +10,7 @@ import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider; +import org.hibernate.test.cache.infinispan.tm.XaConnectionProvider; import org.hibernate.testing.env.ConnectionProviderBuilder; import org.infinispan.commons.util.CloseableIteratorSet; import org.infinispan.context.Flag; @@ -26,8 +27,10 @@ public class MultiTenancyTestCase extends SingleNodeTestCase { private static final String DB1 = "db1"; private static final String DB2 = "db2"; - private final ConnectionProvider db1 = ConnectionProviderBuilder.buildConnectionProvider(DB1); - private final ConnectionProvider db2 = ConnectionProviderBuilder.buildConnectionProvider(DB2); + private final ConnectionProvider db1 + = new XaConnectionProvider(ConnectionProviderBuilder.buildConnectionProvider(DB1)); + private final ConnectionProvider db2 + = new XaConnectionProvider(ConnectionProviderBuilder.buildConnectionProvider(DB2)); @Override protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) { diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaConnectionProvider.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaConnectionProvider.java index 93074c5eaa6f..d44349d822a6 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaConnectionProvider.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaConnectionProvider.java @@ -23,10 +23,19 @@ * @since 3.5 */ public class XaConnectionProvider implements ConnectionProvider { - private static ConnectionProvider actualConnectionProvider = ConnectionProviderBuilder.buildConnectionProvider(); + private final static ConnectionProvider DEFAULT_CONNECTION_PROVIDER = ConnectionProviderBuilder.buildConnectionProvider(); + private final ConnectionProvider actualConnectionProvider; private boolean isTransactional; - public static ConnectionProvider getActualConnectionProvider() { + public XaConnectionProvider() { + this(DEFAULT_CONNECTION_PROVIDER); + } + + public XaConnectionProvider(ConnectionProvider connectionProvider) { + this.actualConnectionProvider = connectionProvider; + } + + public ConnectionProvider getActualConnectionProvider() { return actualConnectionProvider; } From 9541b4fba73d58eea581a8d59130c5d09c296f6e Mon Sep 17 00:00:00 2001 From: Radim Vansa Date: Fri, 19 Jun 2015 16:54:39 +0200 Subject: [PATCH 6/7] HHH-9868 Infinispan 2LC can store stale data * invalidation blocks putFromLoads until the transaction with invalidation is committed * rewritten the naked puts support: timestamp is stored in the pendingPutMap and removal of the record relies on pending puts' idle expiration or piggy-backs on release from putFromLoad --- .../access/PutFromLoadValidator.java | 430 +++++++++--------- .../access/TransactionalAccessDelegate.java | 25 +- .../collection/TransactionalAccess.java | 1 + .../entity/TransactionalAccess.java | 1 + .../naturalid/TransactionalAccess.java | 1 + .../PutFromLoadValidatorUnitTestCase.java | 249 +++++----- ...ollectionRegionAccessStrategyTestCase.java | 6 +- .../AbstractFunctionalTestCase.java | 169 ++++++- .../BasicTransactionalTestCase.java | 4 - .../cluster/DualNodeJtaTransactionImpl.java | 30 +- .../tm/XaTransactionManagerImpl.java | 23 +- 11 files changed, 562 insertions(+), 377 deletions(-) diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java index 69edd85bbf15..87a6d6be9c1d 100644 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java @@ -10,13 +10,13 @@ import javax.transaction.Transaction; import javax.transaction.TransactionManager; import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; +import java.util.HashSet; +import java.util.Iterator; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; import java.util.concurrent.locks.ReentrantLock; import org.hibernate.cache.CacheException; @@ -41,9 +41,9 @@ *
  • Call {@link #registerPendingPut(Object)}
  • *
  • Read the database
  • *
  • Call {@link #acquirePutFromLoadLock(Object)} - *
  • if above returns false, the thread should not cache the data; - * only if above returns true, put data in the cache and...
  • - *
  • then call {@link #releasePutFromLoadLock(Object)}
  • + *
  • if above returns null, the thread should not cache the data; + * only if above returns instance of AcquiredLock, put data in the cache and...
  • + *
  • then call {@link #releasePutFromLoadLock(Object, Lock)}
  • * *

    *

    @@ -53,15 +53,19 @@ * call *

    *

      - *
    • {@link #invalidateKey(Object)} (for a single key invalidation)
    • + *
    • {@link #beginInvalidatingKey(Object)} (for a single key invalidation)
    • *
    • or {@link #invalidateRegion()} (for a general invalidation all pending puts)
    • *
    + * After transaction commit (when the DB is updated) {@link #endInvalidatingKey(Object)} should + * be called in order to allow further attempts to cache entry. *

    *

    *

    * This class also supports the concept of "naked puts", which are calls to - * {@link #acquirePutFromLoadLock(Object)} without a preceding {@link #registerPendingPut(Object)} - * call. + * {@link #acquirePutFromLoadLock(Object)} without a preceding {@link #registerPendingPut(Object)}. + * Besides not acquiring lock in {@link #registerPendingPut(Object)} this can happen when collection + * elements are loaded after the collection has not been found in the cache, where the elements + * don't have their own table but can be listed as 'select ... from Element where collection_id = ...'. *

    * * @author Brian Stansberry @@ -89,26 +93,15 @@ public class PutFromLoadValidator { */ private final ConcurrentMap pendingPuts; - private final ConcurrentMap recentRemovals = new ConcurrentHashMap(); /** - * List of recent removals. Used to ensure we don't leak memory via the recentRemovals map - */ - private final List removalsQueue = new LinkedList(); - /** - * The time when the first element in removalsQueue will expire. No reason to do housekeeping on - * the queue before this time. - */ - private volatile long earliestRemovalTimestamp; - /** - * Lock controlling access to removalsQueue - */ - private final Lock removalsLock = new ReentrantLock(); - - /** - * The time of the last call to regionRemoved(), plus NAKED_PUT_INVALIDATION_PERIOD. All naked + * The time of the last call to {@link #invalidateRegion()}, plus NAKED_PUT_INVALIDATION_PERIOD. All naked * puts will be rejected until the current time is greater than this value. + * NOTE: update only through {@link #invalidationUpdater}! */ - private volatile long invalidationTimestamp; + private volatile long invalidationTimestamp = Long.MIN_VALUE; + + private static final AtomicLongFieldUpdater invalidationUpdater + = AtomicLongFieldUpdater.newUpdater(PutFromLoadValidator.class, "invalidationTimestamp"); /** * Creates a new put from load validator instance. @@ -128,9 +121,7 @@ public PutFromLoadValidator(AdvancedCache cache) { * {@link #registerPendingPut(Object) pre-registered} (aka a "naked put") * will return false. */ - public PutFromLoadValidator( - AdvancedCache cache, - long nakedPutInvalidationPeriod) { + public PutFromLoadValidator(AdvancedCache cache, long nakedPutInvalidationPeriod) { this(cache, cache.getCacheManager(), cache.getTransactionManager(), nakedPutInvalidationPeriod ); @@ -168,81 +159,100 @@ public PutFromLoadValidator(AdvancedCache cache, // ----------------------------------------------------------------- Public + /** + * Marker for lock acquired in {@link #acquirePutFromLoadLock(Object)} + */ + public static class Lock { + protected Lock() {} + } + /** * Acquire a lock giving the calling thread the right to put data in the * cache for the given key. *

    * NOTE: A call to this method that returns true - * should always be matched with a call to {@link #releasePutFromLoadLock(Object)}. + * should always be matched with a call to {@link #releasePutFromLoadLock(Object, Lock)}. *

    * * @param key the key * - * @return true if the lock is acquired and the cache put - * can proceed; false if the data should not be cached + * @return AcquiredLock if the lock is acquired and the cache put + * can proceed; null if the data should not be cached */ - public boolean acquirePutFromLoadLock(Object key) { + public Lock acquirePutFromLoadLock(Object key) { boolean valid = false; boolean locked = false; - final long now = System.currentTimeMillis(); + long now = Long.MIN_VALUE; - try { - final PendingPutMap pending = pendingPuts.get( key ); - if ( pending != null ) { - locked = pending.acquireLock( 100, TimeUnit.MILLISECONDS ); - if ( locked ) { - try { - final PendingPut toCancel = pending.remove( getOwnerForPut() ); - if ( toCancel != null ) { - valid = !toCancel.completed; - toCancel.completed = true; + PendingPutMap pending = pendingPuts.get( key ); + for (;;) { + try { + if (pending != null) { + locked = pending.acquireLock(100, TimeUnit.MILLISECONDS); + if (locked) { + try { + final PendingPut toCancel = pending.remove(getOwnerForPut()); + if (toCancel != null) { + valid = !toCancel.completed; + toCancel.completed = true; + } else { + // this is a naked put + if (pending.hasInvalidator()) { + valid = false; + } else { + if (now == Long.MIN_VALUE) { + now = System.currentTimeMillis(); + } + valid = now > pending.nakedPutsDeadline; + } + } + return valid ? pending : null; + } finally { + if (!valid) { + pending.releaseLock(); + locked = false; + } } + } else { + // oops, we have leaked record for this owner, but we don't want to wait here + return null; } - finally { - if ( !valid ) { - pending.releaseLock(); - locked = false; + } else { + // Key wasn't in pendingPuts, so either this is a "naked put" + // or regionRemoved has been called. Check if we can proceed + long invalidationTimestamp = this.invalidationTimestamp; + if (invalidationTimestamp != Long.MIN_VALUE) { + now = System.currentTimeMillis(); + if (now > invalidationTimestamp) { + // time is +- monotonic se don't let other threads do the expensive currentTimeMillis() + invalidationUpdater.compareAndSet(this, invalidationTimestamp, Long.MIN_VALUE); + } else { + return null; } } - } - } - else { - // Key wasn't in pendingPuts, so either this is a "naked put" - // or regionRemoved has been called. Check if we can proceed - if ( now > invalidationTimestamp ) { - final Long removedTime = recentRemovals.get( key ); - if ( removedTime == null || now > removedTime ) { - // It's legal to proceed. But we have to record this key - // in pendingPuts so releasePutFromLoadLock can find it. - // To do this we basically simulate a normal "register - // then acquire lock" pattern - registerPendingPut( key ); - locked = acquirePutFromLoadLock( key ); - valid = locked; + + PendingPut pendingPut = new PendingPut(getOwnerForPut()); + pending = new PendingPutMap(pendingPut); + PendingPutMap existing = pendingPuts.putIfAbsent(key, pending); + if (existing != null) { + pending = existing; } + // continue in next loop with lock acquisition } - } - } - catch (Throwable t) { - if ( locked ) { - final PendingPutMap toRelease = pendingPuts.get( key ); - if ( toRelease != null ) { - toRelease.releaseLock(); + } catch (Throwable t) { + if (locked) { + pending.releaseLock(); } - } - if ( t instanceof RuntimeException ) { - throw (RuntimeException) t; - } - else if ( t instanceof Error ) { - throw (Error) t; - } - else { - throw new RuntimeException( t ); + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } else if (t instanceof Error) { + throw (Error) t; + } else { + throw new RuntimeException(t); + } } } - - return valid; } /** @@ -251,87 +261,16 @@ else if ( t instanceof Error ) { * * @param key the key */ - public void releasePutFromLoadLock(Object key) { - final PendingPutMap pending = pendingPuts.get( key ); + public void releasePutFromLoadLock(Object key, Lock lock) { + final PendingPutMap pending = (PendingPutMap) lock; if ( pending != null ) { - if ( pending.size() == 0 ) { + if ( pending.canRemove() ) { pendingPuts.remove( key, pending ); } pending.releaseLock(); } } - /** - * Invalidates any {@link #registerPendingPut(Object) previously registered pending puts} ensuring a subsequent call to - * {@link #acquirePutFromLoadLock(Object)} will return false.

    This method will block until any - * concurrent thread that has {@link #acquirePutFromLoadLock(Object) acquired the putFromLoad lock} for the given key - * has released the lock. This allows the caller to be certain the putFromLoad will not execute after this method - * returns, possibly caching stale data.

    - * - * @param key key identifying data whose pending puts should be invalidated - * - * @return true if the invalidation was successful; false if a problem occured (which the - * caller should treat as an exception condition) - */ - public boolean invalidateKey(Object key) { - boolean success = true; - - // Invalidate any pending puts - final PendingPutMap pending = pendingPuts.get( key ); - if ( pending != null ) { - // This lock should be available very quickly, but we'll be - // very patient waiting for it as callers should treat not - // acquiring it as an exception condition - if ( pending.acquireLock( 60, TimeUnit.SECONDS ) ) { - try { - pending.invalidate(); - } - finally { - pending.releaseLock(); - } - } - else { - success = false; - } - } - - // Record when this occurred to invalidate later naked puts - final RecentRemoval removal = new RecentRemoval( key, this.nakedPutInvalidationPeriod ); - recentRemovals.put( key, removal.timestamp ); - - // Don't let recentRemovals map become a memory leak - RecentRemoval toClean = null; - final boolean attemptClean = removal.timestamp > earliestRemovalTimestamp; - removalsLock.lock(); - try { - removalsQueue.add( removal ); - - if ( attemptClean ) { - if ( removalsQueue.size() > 1 ) { - // we have at least one as we just added it - toClean = removalsQueue.remove( 0 ); - } - earliestRemovalTimestamp = removalsQueue.get( 0 ).timestamp; - } - } - finally { - removalsLock.unlock(); - } - - if ( toClean != null ) { - Long cleaned = recentRemovals.get( toClean.key ); - if ( cleaned != null && cleaned.equals( toClean.timestamp ) ) { - cleaned = recentRemovals.remove( toClean.key ); - if ( cleaned != null && !cleaned.equals( toClean.timestamp ) ) { - // Oops; removed the wrong timestamp; restore it - recentRemovals.putIfAbsent( toClean.key, cleaned ); - } - } - } - - return success; - } - /** * Invalidates all {@link #registerPendingPut(Object) previously registered pending puts} ensuring a subsequent call to * {@link #acquirePutFromLoadLock(Object)} will return false.

    This method will block until any @@ -343,15 +282,16 @@ public boolean invalidateKey(Object key) { * caller should treat as an exception condition) */ public boolean invalidateRegion() { - - boolean ok = false; - invalidationTimestamp = System.currentTimeMillis() + this.nakedPutInvalidationPeriod; - + // TODO: not sure what happens with locks acquired *after* calling this method but before + // the actual invalidation + boolean ok = true; + invalidationUpdater.set(this, System.currentTimeMillis() + nakedPutInvalidationPeriod); try { // Acquire the lock for each entry to ensure any ongoing // work associated with it is completed before we return - for ( PendingPutMap entry : pendingPuts.values() ) { + for ( Iterator it = pendingPuts.values().iterator(); it.hasNext(); ) { + PendingPutMap entry = it.next(); if ( entry.acquireLock( 60, TimeUnit.SECONDS ) ) { try { entry.invalidate(); @@ -359,30 +299,15 @@ public boolean invalidateRegion() { finally { entry.releaseLock(); } + it.remove(); } else { ok = false; } } - - removalsLock.lock(); - try { - recentRemovals.clear(); - removalsQueue.clear(); - - ok = true; - - } - finally { - removalsLock.unlock(); - } - } - catch (Exception e) { + } catch (Exception e) { ok = false; } - finally { - earliestRemovalTimestamp = invalidationTimestamp; - } return ok; } @@ -393,8 +318,7 @@ public boolean invalidateRegion() { * wherein it is expected that a database read plus cache put will occur. Calling this method allows the validator to * treat the subsequent acquirePutFromLoadLock as if the database read occurred when this method was * invoked. This allows the validator to compare the timestamp of this call against the timestamp of subsequent removal - * notifications. A put that occurs without this call preceding it is "naked"; i.e the validator must assume the put is - * not valid if any relevant removal has occurred within {@link #NAKED_PUT_INVALIDATION_PERIOD} milliseconds. + * notifications. * * @param key key that will be used for subsequent cache put */ @@ -402,50 +326,83 @@ public void registerPendingPut(Object key) { final PendingPut pendingPut = new PendingPut( getOwnerForPut() ); final PendingPutMap pendingForKey = new PendingPutMap( pendingPut ); - for (; ; ) { - final PendingPutMap existing = pendingPuts.putIfAbsent( key, pendingForKey ); - if ( existing != null ) { - if ( existing.acquireLock( 10, TimeUnit.SECONDS ) ) { - - try { - existing.put( pendingPut ); - final PendingPutMap doublecheck = pendingPuts.putIfAbsent( key, existing ); - if ( doublecheck == null || doublecheck == existing ) { - break; - } - // else we hit a race and need to loop to try again - } - finally { - existing.releaseLock(); + final PendingPutMap existing = pendingPuts.putIfAbsent( key, pendingForKey ); + if ( existing != null ) { + if ( existing.acquireLock( 10, TimeUnit.SECONDS ) ) { + try { + if ( !existing.hasInvalidator() ) { + existing.put(pendingPut); } - } - else { - // Can't get the lock; when we come back we'll be a "naked put" - break; + } finally { + existing.releaseLock(); } } else { - // normal case - break; + // Can't get the lock; when we come back we'll be a "naked put" } } } - // -------------------------------------------------------------- Protected - /** - * Only for use by unit tests; may be removed at any time + * Invalidates any {@link #registerPendingPut(Object) previously registered pending puts} + * and disables further registrations ensuring a subsequent call to {@link #acquirePutFromLoadLock(Object)} + * will return false.

    This method will block until any concurrent thread that has + * {@link #acquirePutFromLoadLock(Object) acquired the putFromLoad lock} for the given key + * has released the lock. This allows the caller to be certain the putFromLoad will not execute after this method + * returns, possibly caching stale data.

    + * After this transaction completes, {@link #endInvalidatingKey(Object)} needs to be called } + * + * @param key key identifying data whose pending puts should be invalidated + * + * @return true if the invalidation was successful; false if a problem occured (which the + * caller should treat as an exception condition) */ - protected int getRemovalQueueLength() { - removalsLock.lock(); - try { - return removalsQueue.size(); + public boolean beginInvalidatingKey(Object key) { + PendingPutMap pending = new PendingPutMap(null); + PendingPutMap prev = pendingPuts.putIfAbsent(key, pending); + if (prev != null) { + pending = prev; } - finally { - removalsLock.unlock(); + if (pending.acquireLock(60, TimeUnit.SECONDS)) { + try { + pending.invalidate(); + pending.addInvalidator(getOwnerForPut(), System.currentTimeMillis() + nakedPutInvalidationPeriod); + } finally { + pending.releaseLock(); + } + return true; + } else { + return false; } } + /** + * Called after the transaction completes, allowing caching of entries. It is possible that this method + * is called without previous invocation of {@link #beginInvalidatingKey(Object)}, then it should be noop. + * + * @param key + * @return + */ + public boolean endInvalidatingKey(Object key) { + PendingPutMap pending = pendingPuts.get(key); + if (pending == null) { + return true; + } + if (pending.acquireLock(60, TimeUnit.SECONDS)) { + try { + pending.removeInvalidator(getOwnerForPut()); + // we can't remove the pending put yet because we wait for naked puts + // pendingPuts should be configured with maxIdle time so won't have memory leak + return true; + } finally { + pending.releaseLock(); + } + } else { + return false; + } + } + + // ---------------------------------------------------------------- Private private Object getOwnerForPut() { @@ -468,10 +425,13 @@ private Object getOwnerForPut() { *

    * This class is NOT THREAD SAFE. All operations on it must be performed with the lock held. */ - private static class PendingPutMap { + private static class PendingPutMap extends Lock { private PendingPut singlePendingPut; private Map fullMap; - private final Lock lock = new ReentrantLock(); + private final java.util.concurrent.locks.Lock lock = new ReentrantLock(); + private Object singleInvalidator; + private Set invalidators; + private long nakedPutsDeadline = Long.MIN_VALUE; PendingPutMap(PendingPut singleItem) { this.singlePendingPut = singleItem; @@ -544,6 +504,41 @@ else if ( fullMap != null ) { fullMap = null; } } + + public void addInvalidator(Object invalidator, long deadline) { + if (invalidators == null) { + if (singleInvalidator == null) { + singleInvalidator = invalidator; + } else { + invalidators = new HashSet(); + invalidators.add(singleInvalidator); + invalidators.add(invalidator); + singleInvalidator = null; + } + } else { + invalidators.add(invalidator); + } + nakedPutsDeadline = Math.max(nakedPutsDeadline, deadline); + } + + public boolean hasInvalidator() { + return singleInvalidator != null || (invalidators != null && !invalidators.isEmpty()); + } + + public void removeInvalidator(Object invalidator) { + if (invalidators == null) { + if (singleInvalidator != null && singleInvalidator.equals(invalidator)) { + singleInvalidator = null; + } + } else { + invalidators.remove(invalidator); + } + } + + public boolean canRemove() { + return size() == 0 && !hasInvalidator() && + (nakedPutsDeadline == Long.MIN_VALUE || nakedPutsDeadline < System.currentTimeMillis()); + } } private static class PendingPut { @@ -554,15 +549,4 @@ private PendingPut(Object owner) { this.owner = owner; } } - - private static class RecentRemoval { - private final Object key; - private final Long timestamp; - - private RecentRemoval(Object key, long nakedPutInvalidationPeriod) { - this.key = key; - timestamp = System.currentTimeMillis() + nakedPutInvalidationPeriod; - } - } - } diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java index bafe2d980025..3c196784e786 100755 --- a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java +++ b/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java @@ -9,7 +9,6 @@ import org.hibernate.cache.CacheException; import org.hibernate.cache.infinispan.impl.BaseRegion; import org.hibernate.cache.infinispan.util.Caches; - import org.infinispan.AdvancedCache; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; @@ -111,7 +110,8 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve return false; } - if ( !putValidator.acquirePutFromLoadLock( key ) ) { + PutFromLoadValidator.Lock lock = putValidator.acquirePutFromLoadLock(key); + if ( lock == null) { if ( TRACE_ENABLED ) { log.tracef( "Put from load lock not acquired for key %s", key ); } @@ -131,7 +131,7 @@ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object ve } } finally { - putValidator.releasePutFromLoadLock( key ); + putValidator.releasePutFromLoadLock( key, lock); } return true; @@ -185,7 +185,7 @@ public boolean update(Object key, Object value, Object currentVersion, Object pr * @throws CacheException if removing the cached item fails */ public void remove(Object key) throws CacheException { - if ( !putValidator.invalidateKey( key ) ) { + if ( !putValidator.beginInvalidatingKey(key)) { throw new CacheException( "Failed to invalidate pending putFromLoad calls for key " + key + " from region " + region.getName() ); @@ -216,7 +216,7 @@ public void removeAll() throws CacheException { * @throws CacheException if evicting the item fails */ public void evict(Object key) throws CacheException { - if ( !putValidator.invalidateKey( key ) ) { + if ( !putValidator.beginInvalidatingKey(key)) { throw new CacheException( "Failed to invalidate pending putFromLoad calls for key " + key + " from region " + region.getName() ); @@ -240,4 +240,19 @@ public void evictAll() throws CacheException { Caches.broadcastEvictAll( cache ); } + /** + * Called when we have finished the attempted update/delete (which may or + * may not have been successful), after transaction completion. This method + * is used by "asynchronous" concurrency strategies. + * + * @param key The item key + * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region} + */ + public void unlockItem(Object key) throws CacheException { + if ( !putValidator.endInvalidatingKey(key) ) { + // TODO: localization + log.warn("Failed to end invalidating pending putFromLoad calls for key " + key + " from region " + + region.getName() + "; the key won't be cached in the future."); + } + } } 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 3c49f911535b..e75d142aef52 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 @@ -74,6 +74,7 @@ public SoftLock lockRegion() throws CacheException { } public void unlockItem(Object key, SoftLock lock) throws CacheException { + delegate.unlockItem(key); } public void unlockRegion(SoftLock lock) throws CacheException { 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 e24e5e4147a8..64319523b706 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 @@ -83,6 +83,7 @@ public SoftLock lockRegion() throws CacheException { } public void unlockItem(Object key, SoftLock lock) throws CacheException { + delegate.unlockItem(key); } public void unlockRegion(SoftLock lock) throws CacheException { 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 41706f6a3a79..4ceb67eedcf9 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 @@ -89,6 +89,7 @@ public SoftLock lockRegion() throws CacheException { @Override public void unlockItem(Object key, SoftLock lock) throws CacheException { + delegate.unlockItem(key); } @Override diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java index 066b1184707f..407d832e3cb8 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java @@ -19,8 +19,6 @@ import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl; -import org.infinispan.AdvancedCache; -import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.CacheManagerCallable; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.util.logging.Log; @@ -30,8 +28,9 @@ import org.junit.Test; import static org.infinispan.test.TestingUtil.withCacheManager; +import static org.infinispan.test.TestingUtil.withTx; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -82,28 +81,13 @@ private void nakedPutTest(final boolean transactional) throws Exception { TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - try { - PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, - transactional ? tm : null, - PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); - if (transactional) { - tm.begin(); - } - boolean lockable = testee.acquirePutFromLoadLock(KEY1); - try { - assertTrue(lockable); - } - finally { - if (lockable) { - testee.releasePutFromLoadLock(KEY1); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, + transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); + exec(transactional, new NakedPut(testee, true)); } }); } + @Test public void testRegisteredPut() throws Exception { registeredPutTest(false); @@ -119,29 +103,12 @@ private void registeredPutTest(final boolean transactional) throws Exception { @Override public void call() { PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, - transactional ? tm : null, - PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); - try { - if (transactional) { - tm.begin(); - } - testee.registerPendingPut(KEY1); - - boolean lockable = testee.acquirePutFromLoadLock(KEY1); - try { - assertTrue(lockable); - } - finally { - if (lockable) { - testee.releasePutFromLoadLock(KEY1); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } + transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); + exec(transactional, new RegularPut(testee)); } }); } + @Test public void testNakedPutAfterKeyRemoval() throws Exception { nakedPutAfterRemovalTest(false, false); @@ -166,34 +133,15 @@ private void nakedPutAfterRemovalTest(final boolean transactional, @Override public void call() { PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, - transactional ? tm : null, - PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); - if (removeRegion) { - testee.invalidateRegion(); - } else { - testee.invalidateKey(KEY1); - } - try { - if (transactional) { - tm.begin(); - } - - boolean lockable = testee.acquirePutFromLoadLock(KEY1); - try { - assertFalse(lockable); - } - finally { - if (lockable) { - testee.releasePutFromLoadLock(KEY1); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } + transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); + Invalidation invalidation = new Invalidation(testee, removeRegion); + NakedPut nakedPut = new NakedPut(testee, false); + exec(transactional, invalidation, nakedPut); } }); } + @Test public void testRegisteredPutAfterKeyRemoval() throws Exception { registeredPutAfterRemovalTest(false, false); @@ -218,31 +166,10 @@ private void registeredPutAfterRemovalTest(final boolean transactional, @Override public void call() { PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, - transactional ? tm : null, - PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); - if (removeRegion) { - testee.invalidateRegion(); - } else { - testee.invalidateKey(KEY1); - } - try { - if (transactional) { - tm.begin(); - } - testee.registerPendingPut(KEY1); - - boolean lockable = testee.acquirePutFromLoadLock(KEY1); - try { - assertTrue(lockable); - } - finally { - if (lockable) { - testee.releasePutFromLoadLock(KEY1); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } + transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); + Invalidation invalidation = new Invalidation(testee, removeRegion); + RegularPut regularPut = new RegularPut(testee); + exec(transactional, invalidation, regularPut); } }); @@ -272,8 +199,7 @@ private void registeredPutWithInterveningRemovalTest( @Override public void call() { PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, - transactional ? tm : null, - PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); + transactional ? tm : null, PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD); try { if (transactional) { tm.begin(); @@ -282,17 +208,18 @@ public void call() { if (removeRegion) { testee.invalidateRegion(); } else { - testee.invalidateKey(KEY1); + testee.beginInvalidatingKey(KEY1); } - boolean lockable = testee.acquirePutFromLoadLock(KEY1); + PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1); try { - assertFalse(lockable); + assertNull(lock); } finally { - if (lockable) { - testee.releasePutFromLoadLock(KEY1); + if (lock != null) { + testee.releasePutFromLoadLock(KEY1, lock); } + testee.endInvalidatingKey(KEY1); } } catch (Exception e) { throw new RuntimeException(e); @@ -300,6 +227,7 @@ public void call() { } }); } + @Test public void testDelayedNakedPutAfterKeyRemoval() throws Exception { delayedNakedPutAfterRemovalTest(false, false); @@ -324,12 +252,13 @@ private void delayedNakedPutAfterRemovalTest( TestCacheManagerFactory.createCacheManager(false)) { @Override public void call() { - PutFromLoadValidator testee = new TestValidator(cm.getCache().getAdvancedCache(), cm, + PutFromLoadValidator testee = new PutFromLoadValidator(cm.getCache().getAdvancedCache(), cm, transactional ? tm : null, 100); if (removeRegion) { testee.invalidateRegion(); } else { - testee.invalidateKey(KEY1); + testee.beginInvalidatingKey(KEY1); + testee.endInvalidatingKey(KEY1); } try { if (transactional) { @@ -337,12 +266,12 @@ public void call() { } Thread.sleep(110); - boolean lockable = testee.acquirePutFromLoadLock(KEY1); + PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1); try { - assertTrue(lockable); + assertNotNull(lock); } finally { - if (lockable) { - testee.releasePutFromLoadLock(KEY1); + if (lock != null) { + testee.releasePutFromLoadLock(KEY1, null); } } } catch (Exception e) { @@ -384,12 +313,13 @@ public void run() { testee.registerPendingPut(KEY1); registeredLatch.countDown(); registeredLatch.await(5, TimeUnit.SECONDS); - if (testee.acquirePutFromLoadLock(KEY1)) { + PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1); + if (lock != null) { try { log.trace("Put from load lock acquired for key = " + KEY1); success.incrementAndGet(); } finally { - testee.releasePutFromLoadLock(KEY1); + testee.releasePutFromLoadLock(KEY1, lock); } } else { log.trace("Unable to acquired putFromLoad lock for key = " + KEY1); @@ -448,7 +378,8 @@ public void call() { Callable pferCallable = new Callable() { public Boolean call() throws Exception { testee.registerPendingPut(KEY1); - if (testee.acquirePutFromLoadLock(KEY1)) { + PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1); + if (lock != null) { try { removeLatch.countDown(); pferLatch.await(); @@ -456,7 +387,7 @@ public Boolean call() throws Exception { return Boolean.TRUE; } finally { - testee.releasePutFromLoadLock(KEY1); + testee.releasePutFromLoadLock(KEY1, lock); } } return Boolean.FALSE; @@ -467,7 +398,7 @@ public Boolean call() throws Exception { public Void call() throws Exception { removeLatch.await(); if (keyOnly) { - testee.invalidateKey(KEY1); + testee.beginInvalidatingKey(KEY1); } else { testee.invalidateRegion(); } @@ -500,18 +431,104 @@ public Void call() throws Exception { }); } - private static class TestValidator extends PutFromLoadValidator { + protected void exec(boolean transactional, Callable... callables) { + try { + if (transactional) { + for (Callable c : callables) { + withTx(tm, c); + } + } else { + for (Callable c : callables) { + c.call(); + } + } + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private class Invalidation implements Callable { + private PutFromLoadValidator putFromLoadValidator; + private boolean removeRegion; - protected TestValidator(AdvancedCache cache, EmbeddedCacheManager cm, - TransactionManager transactionManager, - long nakedPutInvalidationPeriod) { - super(cache, cm, transactionManager, nakedPutInvalidationPeriod); + public Invalidation(PutFromLoadValidator putFromLoadValidator, boolean removeRegion) { + this.putFromLoadValidator = putFromLoadValidator; + this.removeRegion = removeRegion; } @Override - public int getRemovalQueueLength() { - return super.getRemovalQueueLength(); + public Void call() throws Exception { + if (removeRegion) { + boolean success = putFromLoadValidator.invalidateRegion(); + assertTrue(success); + } else { + boolean success = putFromLoadValidator.beginInvalidatingKey(KEY1); + assertTrue(success); + success = putFromLoadValidator.endInvalidatingKey(KEY1); + assertTrue(success); + } + return null; } + } + + private class RegularPut implements Callable { + private PutFromLoadValidator putFromLoadValidator; + + public RegularPut(PutFromLoadValidator putFromLoadValidator) { + this.putFromLoadValidator = putFromLoadValidator; + } + + @Override + public Void call() throws Exception { + try { + putFromLoadValidator.registerPendingPut(KEY1); + PutFromLoadValidator.Lock lock = putFromLoadValidator.acquirePutFromLoadLock(KEY1); + try { + assertNotNull(lock); + } finally { + if (lock != null) { + putFromLoadValidator.releasePutFromLoadLock(KEY1, lock); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } + } + + private class NakedPut implements Callable { + private final PutFromLoadValidator testee; + private final boolean expectSuccess; + + public NakedPut(PutFromLoadValidator testee, boolean expectSuccess) { + this.testee = testee; + this.expectSuccess = expectSuccess; + } + + @Override + public Void call() throws Exception { + try { + PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(KEY1); + try { + if (expectSuccess) { + assertNotNull(lock); + } else { + assertNull(lock); + } + } + finally { + if (lock != null) { + testee.releasePutFromLoadLock(KEY1, lock); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } } } 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 af8aedf97b1c..3c30c64497fe 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 @@ -155,8 +155,8 @@ public void call() { PutFromLoadValidator validator = new PutFromLoadValidator(remoteCollectionRegion.getCache(), cm, remoteTm, 20000) { @Override - public boolean acquirePutFromLoadLock(Object key) { - boolean acquired = super.acquirePutFromLoadLock( key ); + public Lock acquirePutFromLoadLock(Object key) { + Lock lock = super.acquirePutFromLoadLock( key ); try { removeLatch.countDown(); pferLatch.await( 2, TimeUnit.SECONDS ); @@ -169,7 +169,7 @@ public boolean acquirePutFromLoadLock(Object key) { log.error( "Error", e ); throw new RuntimeException( "Error", e ); } - return acquired; + return lock; } }; diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java index bf7045443624..c21b493d9398 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java @@ -6,18 +6,33 @@ */ package org.hibernate.test.cache.infinispan.functional; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.Phaser; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.hibernate.PessimisticLockException; import org.hibernate.Session; +import org.hibernate.cache.infinispan.InfinispanRegionFactory; +import org.hibernate.cache.infinispan.entity.EntityRegionImpl; +import org.hibernate.cache.spi.Region; import org.hibernate.stat.SecondLevelCacheStatistics; import org.hibernate.stat.Statistics; +import org.hibernate.testing.TestForIssue; +import org.infinispan.AdvancedCache; +import org.infinispan.commands.read.GetKeyValueCommand; +import org.infinispan.context.InvocationContext; +import org.infinispan.interceptors.base.BaseCustomInterceptor; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; import org.junit.Test; -import java.util.Map; -import java.util.concurrent.Callable; - import static org.infinispan.test.TestingUtil.withTx; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; /** * Parent tests for both transactional and @@ -122,4 +137,152 @@ public Void call() throws Exception { }); } + @Test + @TestForIssue(jiraKey = "HHH-9868") + public void testConcurrentRemoveAndPutFromLoad() throws Exception { + final Item item = new Item( "chris", "Chris's Item" ); + + withTx(tm, () -> { + Session s = openSession(); + s.getTransaction().begin(); + s.persist(item); + s.getTransaction().commit(); + s.close(); + return null; + }); + Region region = sessionFactory().getSecondLevelCacheRegion(Item.class.getName()); + + Phaser deletePhaser = new Phaser(2); + Phaser getPhaser = new Phaser(2); + HookInterceptor hook = new HookInterceptor(); + + AdvancedCache entityCache = ((EntityRegionImpl) region).getCache(); + AdvancedCache pendingPutsCache = entityCache.getCacheManager().getCache( + entityCache.getName() + "-" + InfinispanRegionFactory.PENDING_PUTS_CACHE_NAME).getAdvancedCache(); + pendingPutsCache.addInterceptor(hook, 0); + + Thread deleteThread = new Thread(() -> { + try { + withTx(tm, () -> { + Session s = openSession(); + log.trace("Session opened"); + s.getTransaction().begin(); + log.trace("TX started"); + Item loadedItem = s.get(Item.class, item.getId()); + assertNotNull(loadedItem); + arriveAndAwait(deletePhaser); + arriveAndAwait(deletePhaser); + log.trace("Item loaded"); + s.delete(loadedItem); + log.trace("Item deleted"); + s.getTransaction().commit(); + log.trace("TX committed"); + // start get-thread here + arriveAndAwait(deletePhaser); + arriveAndAwait(deletePhaser); + s.close(); + log.trace("Session closed"); + return null; + }); + } catch (Exception e) { + throw new RuntimeException(e); + } + }, "delete-thread"); + Thread getThread = new Thread(() -> { + try { + withTx(tm, () -> { + Session s = openSession(); + log.trace("Session opened"); + s.getTransaction().begin(); + log.trace("TX started"); + // DB load should happen before the record is deleted, + // putFromLoad should happen after deleteThread ends + Item loadedItem = s.get(Item.class, item.getId()); + assertNotNull(loadedItem); + s.close(); + log.trace("Session closed"); + return null; + }); + } catch (PessimisticLockException e) { + // If we end up here, database locks guard us against situation tested + // in this case and HHH-9868 cannot happen. + // (delete-thread has ITEMS table write-locked and we try to acquire read-lock) + try { + arriveAndAwait(getPhaser); + arriveAndAwait(getPhaser); + } catch (Exception e1) { + throw new RuntimeException(e1); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + }, "get-thread"); + + deleteThread.start(); + // deleteThread loads the entity + arriveAndAwait(deletePhaser); + withTx(tm, () -> { + sessionFactory().getCache().evictEntity(Item.class, item.getId()); + assertFalse(sessionFactory().getCache().containsEntity(Item.class, item.getId())); + return null; + }); + arriveAndAwait(deletePhaser); + // delete thread invalidates PFER + arriveAndAwait(deletePhaser); + // get thread gets the entity from DB + hook.block(getPhaser, getThread); + getThread.start(); + arriveAndAwait(getPhaser); + arriveAndAwait(deletePhaser); + // delete thread finishes the remove from DB and cache + deleteThread.join(); + hook.unblock(); + arriveAndAwait(getPhaser); + // get thread puts the entry into cache + getThread.join(); + + withTx(tm, () -> { + Session s = openSession(); + s.getTransaction().begin(); + Item loadedItem = s.get(Item.class, item.getId()); + assertNull(loadedItem); + s.getTransaction().commit(); + s.close(); + return null; + }); + } + + protected static void arriveAndAwait(Phaser phaser) throws TimeoutException, InterruptedException { + phaser.awaitAdvanceInterruptibly(phaser.arrive(), 10, TimeUnit.SECONDS); + } + + private static class HookInterceptor extends BaseCustomInterceptor { + Phaser phaser; + Thread thread; + + public synchronized void block(Phaser phaser, Thread thread) { + this.phaser = phaser; + this.thread = thread; + } + + public synchronized void unblock() { + phaser = null; + thread = null; + } + + @Override + public Object visitGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable { + Phaser phaser; + Thread thread; + synchronized (this) { + phaser = this.phaser; + thread = this.thread; + } + if (phaser != null && Thread.currentThread() == thread) { + arriveAndAwait(phaser); + arriveAndAwait(phaser); + } + return super.visitGetKeyValueCommand(ctx, command); + } + } } diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicTransactionalTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicTransactionalTestCase.java index ccdecf4bdd4a..6fca62927788 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicTransactionalTestCase.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicTransactionalTestCase.java @@ -11,7 +11,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; import org.hibernate.Cache; import org.hibernate.Criteria; @@ -19,12 +18,10 @@ import org.hibernate.NaturalIdLoadAccess; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.cache.infinispan.access.PutFromLoadValidator; import org.hibernate.cache.spi.entry.CacheEntry; import org.hibernate.criterion.Restrictions; import org.hibernate.stat.SecondLevelCacheStatistics; import org.hibernate.stat.Statistics; - import org.hibernate.testing.TestForIssue; import org.junit.After; import org.junit.Test; @@ -954,7 +951,6 @@ public Citizen call() throws Exception { // TODO: Clear caches manually via cache manager (it's faster!!) this.cleanupCache(); - Thread.sleep(PutFromLoadValidator.NAKED_PUT_INVALIDATION_PERIOD + TimeUnit.SECONDS.toMillis(1)); stats.setStatisticsEnabled( true ); stats.clear(); diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionImpl.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionImpl.java index 73d68de78b38..83656d776fe3 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionImpl.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionImpl.java @@ -6,13 +6,6 @@ */ package org.hibernate.test.cache.infinispan.functional.cluster; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; import javax.transaction.RollbackException; @@ -23,6 +16,13 @@ import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; @@ -62,9 +62,11 @@ public void commit() throws RollbackException, HeuristicMixedException, } else { status = Status.STATUS_PREPARING; - for (int i = 0; i < synchronizations.size(); i++) { - Synchronization s = (Synchronization) synchronizations.get(i); - s.beforeCompletion(); + if (synchronizations != null) { + for (int i = 0; i < synchronizations.size(); i++) { + Synchronization s = (Synchronization) synchronizations.get(i); + s.beforeCompletion(); + } } if (!runXaResourcePrepare()) { @@ -89,9 +91,11 @@ public void commit() throws RollbackException, HeuristicMixedException, status = Status.STATUS_COMMITTED; - for (int i = 0; i < synchronizations.size(); i++) { - Synchronization s = (Synchronization) synchronizations.get(i); - s.afterCompletion(status); + if (synchronizations != null) { + for (int i = 0; i < synchronizations.size(); i++) { + Synchronization s = (Synchronization) synchronizations.get(i); + s.afterCompletion(status); + } } // status = Status.STATUS_NO_TRANSACTION; diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionManagerImpl.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionManagerImpl.java index a02943159dae..17ae60596cd7 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionManagerImpl.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionManagerImpl.java @@ -23,41 +23,44 @@ */ public class XaTransactionManagerImpl implements TransactionManager { private static final XaTransactionManagerImpl INSTANCE = new XaTransactionManagerImpl(); - private XaTransactionImpl currentTransaction; + private final ThreadLocal currentTransaction = new ThreadLocal<>(); public static XaTransactionManagerImpl getInstance() { return INSTANCE; } public int getStatus() throws SystemException { + XaTransactionImpl currentTransaction = this.currentTransaction.get(); return currentTransaction == null ? Status.STATUS_NO_TRANSACTION : currentTransaction.getStatus(); } public Transaction getTransaction() throws SystemException { - return currentTransaction; + return currentTransaction.get(); } public XaTransactionImpl getCurrentTransaction() { - return currentTransaction; + return currentTransaction.get(); } public void begin() throws NotSupportedException, SystemException { - currentTransaction = new XaTransactionImpl(this); + if (currentTransaction.get() != null) throw new IllegalStateException("Transaction already started."); + currentTransaction.set(new XaTransactionImpl(this)); } public Transaction suspend() throws SystemException { - Transaction suspended = currentTransaction; - currentTransaction = null; + Transaction suspended = currentTransaction.get(); + currentTransaction.remove(); return suspended; } public void resume(Transaction transaction) throws InvalidTransactionException, IllegalStateException, SystemException { - currentTransaction = (XaTransactionImpl) transaction; + currentTransaction.set((XaTransactionImpl) transaction); } public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException { + XaTransactionImpl currentTransaction = this.currentTransaction.get(); if (currentTransaction == null) { throw new IllegalStateException("no current transaction to commit"); } @@ -65,6 +68,7 @@ public void commit() throws RollbackException, HeuristicMixedException, Heuristi } public void rollback() throws IllegalStateException, SecurityException, SystemException { + XaTransactionImpl currentTransaction = this.currentTransaction.get(); if (currentTransaction == null) { throw new IllegalStateException("no current transaction"); } @@ -72,6 +76,7 @@ public void rollback() throws IllegalStateException, SecurityException, SystemEx } public void setRollbackOnly() throws IllegalStateException, SystemException { + XaTransactionImpl currentTransaction = this.currentTransaction.get(); if (currentTransaction == null) { throw new IllegalStateException("no current transaction"); } @@ -82,8 +87,6 @@ public void setTransactionTimeout(int i) throws SystemException { } void endCurrent(Transaction transaction) { - if (transaction == currentTransaction) { - currentTransaction = null; - } + currentTransaction.remove(); } } From f61ef64cf084a7505aa4723d59ee386ca256d585 Mon Sep 17 00:00:00 2001 From: Radim Vansa Date: Fri, 19 Jun 2015 17:23:22 +0200 Subject: [PATCH 7/7] Stress test verifying correctness of reads and writes. --- .../stress/CorrectnessTestCase.java | 595 ++++++++++++++++++ .../infinispan/stress/entities/Address.java | 4 +- .../infinispan/stress/entities/Family.java | 9 +- 3 files changed, 601 insertions(+), 7 deletions(-) create mode 100644 hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/CorrectnessTestCase.java diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/CorrectnessTestCase.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/CorrectnessTestCase.java new file mode 100644 index 000000000000..a4cb2668c347 --- /dev/null +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/CorrectnessTestCase.java @@ -0,0 +1,595 @@ +/* + * 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.stress; + +import javax.transaction.Status; +import javax.transaction.TransactionManager; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Environment; +import org.hibernate.criterion.Restrictions; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.RootClass; +import org.hibernate.test.cache.infinispan.stress.entities.Address; +import org.hibernate.test.cache.infinispan.stress.entities.Family; +import org.hibernate.test.cache.infinispan.stress.entities.Person; +import org.infinispan.util.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Tries to execute random operations for {@link #EXECUTION_TIME} and then verify the log for correctness. + * + * Assumes serializable consistency. + * + * @author Radim Vansa + */ +@Ignore // as long-running test, we'll execute it only by hand +public class CorrectnessTestCase { + static final org.infinispan.util.logging.Log log = LogFactory.getLog(CorrectnessTestCase.class); + static final long EXECUTION_TIME = TimeUnit.MINUTES.toMillis(5); + static final int NUM_THREADS = 10; + static final int NUM_FAMILIES = 1; + static final int NUM_ACCESS_AFTER_REMOVAL = NUM_THREADS * 2; + static final String REMOVED = "__REMOVED__"; + + AtomicInteger timestampGenerator = new AtomicInteger(); + ConcurrentSkipListMap familyIds = new ConcurrentSkipListMap<>(); + SessionFactory sessionFactory; + TransactionManager tm; + volatile boolean running = true; + + ThreadLocal>>> familyNames = new ThreadLocal>>>() { + @Override + protected Map>> initialValue() { + return new HashMap<>(); + } + }; + ThreadLocal>>>> familyMembers = new ThreadLocal>>>>() { + @Override + protected Map>>> initialValue() { + return new HashMap<>(); + } + }; + + @Before + public void beforeClass() { + StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().enableAutoClose() + .applySetting( Environment.USE_SECOND_LEVEL_CACHE, "true" ) + .applySetting( Environment.USE_QUERY_CACHE, "true" ) + .applySetting( Environment.DRIVER, "org.h2.Driver" ) + .applySetting( Environment.URL, "jdbc:h2:mem:test") + .applySetting( Environment.DIALECT, H2Dialect.class.getName() ) + .applySetting( Environment.HBM2DDL_AUTO, "create-drop" ) + .applySetting( Environment.CACHE_REGION_FACTORY, "org.hibernate.cache.infinispan.InfinispanRegionFactory" ) + .applySetting( Environment.JTA_PLATFORM, "org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" ) + .applySetting( Environment.GENERATE_STATISTICS, "false" ) + ; + + StandardServiceRegistry registry = ssrb.build(); + + Metadata metadata = buildMetadata( registry ); + + sessionFactory = metadata.buildSessionFactory(); + + tm = com.arjuna.ats.jta.TransactionManager.transactionManager(); + } + + @After + public void afterClass() { + sessionFactory.close(); + } + + public static Class[] getAnnotatedClasses() { + return new Class[] {Family.class, Person.class, Address.class}; + } + + private static Metadata buildMetadata(StandardServiceRegistry registry) { + final String cacheStrategy = "transactional"; + + MetadataSources metadataSources = new MetadataSources( registry ); + for ( Class entityClass : getAnnotatedClasses() ) { + metadataSources.addAnnotatedClass( entityClass ); + } + + Metadata metadata = metadataSources.buildMetadata(); + + for ( PersistentClass entityBinding : metadata.getEntityBindings() ) { + if (!entityBinding.isInherited()) { + ( (RootClass) entityBinding ).setCacheConcurrencyStrategy( cacheStrategy); + } + } + + for ( Collection collectionBinding : metadata.getCollectionBindings() ) { + collectionBinding.setCacheConcurrencyStrategy( cacheStrategy ); + } + + return metadata; + } + + @Test + public void test() throws InterruptedException, ExecutionException { + ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS); + + Map>> allFamilyNames = new HashMap<>(); + Map>>> allFamilyMembers = new HashMap<>(); + + running = true; + List> futures = new ArrayList<>(); + for (int i = 0; i < NUM_THREADS; ++i) { + futures.add(exec.submit(() -> { + ThreadLocalRandom random = ThreadLocalRandom.current(); + while (running) { + Operation operation; + if (familyIds.size() < NUM_FAMILIES) { + operation = new InsertFamily(); + } else { + int r = random.nextInt(100); + if (r == 0) operation = new InvalidateCache(); + else if (r < 5) operation = new QueryFamilies(); + else if (r < 10) operation = new RemoveFamily(); + else if (r < 20) operation = new UpdateFamily(); + else if (r < 35) operation = new AddMember(); + else if (r < 50) operation = new RemoveMember(); + else operation = new ReadFamily(r < 75); + } + try { + operation.run(); + } catch (Exception e) { + // ignore exceptions from optimistic failures + } + } + synchronized (allFamilyNames) { + for (Map.Entry>> entry : familyNames.get().entrySet()) { + List> list = allFamilyNames.get(entry.getKey()); + if (list == null) allFamilyNames.put(entry.getKey(), list = new ArrayList<>()); + list.addAll(entry.getValue()); + } + for (Map.Entry>>> entry : familyMembers.get().entrySet()) { + List>> list = allFamilyMembers.get(entry.getKey()); + if (list == null) allFamilyMembers.put(entry.getKey(), list = new ArrayList<>()); + list.addAll(entry.getValue()); + } + } + return null; + })); + } + Thread.sleep(EXECUTION_TIME); + running = false; + exec.shutdown(); + if (!exec.awaitTermination(1000, TimeUnit.SECONDS)) throw new IllegalStateException(); + for (Future f : futures) { + f.get(); // check for exceptions + } + + log.infof("Generated %d timestamps%n", timestampGenerator.get()); + AtomicInteger created = new AtomicInteger(); + AtomicInteger removed = new AtomicInteger(); + ForkJoinPool threadPool = ForkJoinPool.commonPool(); + ArrayList> tasks = new ArrayList<>(); + for (List> list : allFamilyNames.values()) { + tasks.add(threadPool.submit(() -> { + created.incrementAndGet(); + NavigableMap>> logByTime = getWritesAtTime(list); + checkCorrectness(list, logByTime); + if (list.stream().anyMatch(l -> !l.read && l.getValue() == null)) { + removed.incrementAndGet(); + } + })); + } + for (List>> list : allFamilyMembers.values()) { + tasks.add(threadPool.submit(() -> { + NavigableMap>>> logByTime = getWritesAtTime(list); + checkCorrectness(list, logByTime); + })); + } + for (ForkJoinTask task : tasks) { + task.get(); // propagate exception + } + log.infof("Created %d families, removed %d%n", created.get(), removed.get()); + } + + private NavigableMap>> getWritesAtTime(List> list) { + NavigableMap>> writes = new TreeMap<>(); + for (Log log : list) { + if (log.read) continue; + for (int time = log.before; time <= log.after; ++time) { + List> onTime = writes.get(time); + if (onTime == null) { + writes.put(time, onTime = new ArrayList<>()); + } + onTime.add(log); + } + } + return writes; + } + + private void checkCorrectness(List> logs, NavigableMap>> writesByTime) { + int nullReads = 0, reads = 0, writes = 0; + for (Log read : logs) { + if (!read.read) { + writes++; + continue; + } + if (read.getValue() == null || isEmptyCollection(read)) nullReads++; + else reads++; + + Map> possibleValues = new HashMap<>(); + for (List> list : writesByTime.subMap(read.before, true, read.after, true).values()) { + for (Log write : list) { + if (read.precedes(write)) continue; + possibleValues.put(write.getValue(), write); + } + } + int startOfLastWriteBeforeRead = 0; + for (Map.Entry>> entry : writesByTime.headMap(read.before, false).descendingMap().entrySet()) { + int time = entry.getKey(); + if (time < startOfLastWriteBeforeRead) break; + for (Log write : entry.getValue()) { + if (write.after < read.before && write.before > startOfLastWriteBeforeRead) { + startOfLastWriteBeforeRead = write.before; + } + possibleValues.put(write.getValue(), write); + } + } + + if (!possibleValues.containsKey(read.getValue())) { + throw new IllegalStateException(String.format("R: %d .. %d (%s, %s) -> %s not in %s (%d+)", + read.before, read.after, read.threadName, new SimpleDateFormat("HH:mm:ss,SSS").format(new Date(read.wallClockTime)), + read.getValue(), possibleValues.values(), startOfLastWriteBeforeRead)); + } + } + log.infof("Checked %d null reads, %d reads and %d writes%n", nullReads, reads, writes); + } + + private static boolean isEmptyCollection(Log read) { + return read.getValue() instanceof java.util.Collection && ((java.util.Collection) read.getValue()).isEmpty(); + } + + private abstract class Operation { + public abstract void run() throws Exception; + + protected void withSession(Consumer consumer) throws Exception { + tm.begin(); + try { + Session s = sessionFactory.openSession(); + s.getTransaction().begin(); + consumer.accept(s); + s.getTransaction().commit(); + s.close(); + } catch (RuntimeException e) { + tm.setRollbackOnly(); + throw e; + } finally { + if (tm.getStatus() == Status.STATUS_ACTIVE) { + tm.commit(); + } else { + tm.rollback(); + } + } + } + + protected void withRandomFamily(BiConsumer consumer, Optional familyNameUpdate, Optional> familyMembersUpdate) throws Exception { + int id = randomFamilyId(ThreadLocalRandom.current()); + int before = timestampGenerator.getAndIncrement(); + log.tracef("Started %s at %d", getClass().getSimpleName(), before); + Log familyNameLog = new Log<>(true); + Log> familyMembersLog = new Log<>(true); + + withSession(s -> { + Family f = s.get(Family.class, id); + if (f == null) { + familyNameLog.setValue(null); + familyMembersLog.setValue(Collections.EMPTY_SET); + familyNotFound(id); + } else { + familyNameLog.setValue(f.getName()); + familyMembersLog.setValue(membersToNames(f.getMembers())); + consumer.accept(s, f); + } + }); + + int after = timestampGenerator.getAndIncrement(); + log.tracef("Finished %s at %d", getClass().getSimpleName(), after); + familyNameLog.setTimes(before, after); + familyMembersLog.setTimes(before, after); + + getRecordList(familyNames, id).add(familyNameLog); + getRecordList(familyMembers, id).add(familyMembersLog); + + if (familyNameLog.getValue() != null) { + if (familyNameUpdate.isPresent()) { + getRecordList(familyNames, id).add(new Log<>(before, after, familyNameUpdate.get() == REMOVED ? null : familyNameUpdate.get(), false, familyNameLog)); + } + if (familyMembersUpdate.isPresent()) { + getRecordList(familyMembers, id).add(new Log<>(before, after, familyMembersUpdate.get(), false, familyMembersLog)); + } + } + } + } + + private class InsertFamily extends Operation { + @Override + public void run() throws Exception { + Family family = createFamily(); + int before = timestampGenerator.getAndIncrement(); + log.trace("Started InsertFamily at " + before); + withSession(s -> s.persist(family)); + familyIds.put(family.getId(), new AtomicInteger(NUM_ACCESS_AFTER_REMOVAL)); + int after = timestampGenerator.getAndIncrement(); + log.trace("Finished InsertFamily at " + after); + getRecordList(familyNames, family.getId()).add(new Log<>(before, after, family.getName(), false)); + getRecordList(familyMembers, family.getId()).add(new Log<>(before, after, membersToNames(family.getMembers()), false)); + } + } + + private Set membersToNames(Set members) { + return members.stream().map(p -> p.getFirstName()).collect(Collectors.toSet()); + } + + private class ReadFamily extends Operation { + private final boolean evict; + + public ReadFamily(boolean evict) { + this.evict = evict; + } + + @Override + public void run() throws Exception { + withRandomFamily((s, f) -> { + if (evict) { + sessionFactory.getCache().evictEntity(Family.class, f.getId()); + } + }, Optional.empty(), Optional.empty()); + } + } + + private class UpdateFamily extends Operation { + @Override + public void run() throws Exception { + String newName = randomString(ThreadLocalRandom.current()); + withRandomFamily((s, f) -> { + f.setName(newName); + s.persist(f); + }, Optional.of(newName), Optional.empty()); + } + } + + private class RemoveFamily extends Operation { + @Override + public void run() throws Exception { + withRandomFamily((s, f) -> s.delete(f), Optional.of(REMOVED), Optional.of(Collections.EMPTY_SET)); + } + } + + private abstract class MemberOperation extends Operation { + @Override + public void run() throws Exception { + Set newMembers = new HashSet<>(); + withRandomFamily((s, f) -> { + updateMembers(s, ThreadLocalRandom.current(), f); + newMembers.addAll(membersToNames(f.getMembers())); + s.persist(f); + }, Optional.empty(), Optional.of(newMembers)); + } + + protected abstract void updateMembers(Session s, ThreadLocalRandom random, Family f); + } + + private class AddMember extends MemberOperation { + protected void updateMembers(Session s, ThreadLocalRandom random, Family f) { + f.getMembers().add(createPerson(random, f)); + } + } + + private class RemoveMember extends MemberOperation { + @Override + protected void updateMembers(Session s, ThreadLocalRandom random, Family f) { + int numMembers = f.getMembers().size(); + if (numMembers > 0) { + Iterator it = f.getMembers().iterator(); + Person person = null; + for (int i = random.nextInt(numMembers); i >= 0; --i) { + person = it.next(); + } + it.remove(); + if (person != null) { + s.delete(person); + } + } + } + } + + private class QueryFamilies extends Operation { + final static int MAX_RESULTS = 10; + + @Override + public void run() throws Exception { + String prefix = new StringBuilder(2) + .append((char) ThreadLocalRandom.current().nextInt('A', 'Z' + 1)).append('%').toString(); + int[] ids = new int[MAX_RESULTS]; + String[] names = new String[MAX_RESULTS]; + Set[] members = new Set[MAX_RESULTS]; + + int before = timestampGenerator.getAndIncrement(); + log.tracef("Started QueryFamilies at %d", before); + withSession(s -> { + List results = s.createCriteria(Family.class) + .add(Restrictions.like("name", prefix)) + .setMaxResults(MAX_RESULTS) + .setCacheable(true) + .list(); + int index = 0; + for (Family f : results) { + ids[index] = f.getId(); + names[index] = f.getName(); + members[index] = membersToNames(f.getMembers()); + ++index; + } + }); + + int after = timestampGenerator.getAndIncrement(); + log.tracef("Finsihed QueryFamilies at %d", after); + for (int index = 0; index < MAX_RESULTS; ++index) { + if (names[index] == null) break; + getRecordList(familyNames, ids[index]).add(new Log<>(before, after, names[index], true)); + getRecordList(familyMembers, ids[index]).add(new Log<>(before, after, members[index], true)); + } + } + } + + private class InvalidateCache extends Operation { + @Override + public void run() throws Exception { + log.trace("Invalidating all caches"); + tm.begin(); + try { + sessionFactory.getCache().evictAllRegions(); + } catch (RuntimeException e) { + tm.setRollbackOnly(); + throw e; + } finally { + if (tm.getStatus() == Status.STATUS_ACTIVE) { + tm.commit(); + } else { + tm.rollback(); + } + } + } + } + + private void familyNotFound(int id) { + AtomicInteger access = familyIds.get(id); + if (access == null) return; + if (access.decrementAndGet() == 0) { + familyIds.remove(id); + } + } + + private List getRecordList(ThreadLocal>> tlListMap, int id) { + Map> map = tlListMap.get(); + List list = map.get(id); + if (list == null) map.put(id, list = new ArrayList<>()); + return list; + } + + private int randomFamilyId(ThreadLocalRandom random) { + Integer first = familyIds.firstKey(); + Integer last = familyIds.lastKey(); + if (first == null || last == null) return 0; + return familyIds.ceilingKey(random.nextInt(first, last + 1)); + } + + private static Family createFamily() { + ThreadLocalRandom random = ThreadLocalRandom.current(); + String familyName = randomString(random); + Family f = new Family(familyName); + HashSet members = new HashSet<>(); + members.add(createPerson(random, f)); + f.setMembers(members); + return f; + } + + private static Person createPerson(ThreadLocalRandom random, Family family) { + return new Person(randomString(random), family); + } + + private static String randomString(ThreadLocalRandom random) { + StringBuilder sb = new StringBuilder(10); + for (int i = 0; i < 10; ++i) { + sb.append((char) random.nextInt('A', 'Z' + 1)); + } + return sb.toString(); + } + + private class Log { + int before; + int after; + T value; + boolean read; + Log[] preceding; + String threadName; + long wallClockTime; + + public Log(int time) { + this(); + this.before = time; + this.after = time; + } + + public Log(int before, int after, T value, boolean read, Log... preceding) { + this(); + this.before = before; + this.after = after; + this.value = value; + this.read = read; + this.preceding = preceding; + } + + public Log(boolean read) { + this(); + this.read = read; + } + + protected Log() { + threadName = Thread.currentThread().getName(); + wallClockTime = System.currentTimeMillis(); + } + + public void setTimes(int before, int after) { + this.before = before; + this.after = after; + } + + public void setValue(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + public boolean precedes(Log write) { + if (write.preceding == null) return false; + for (Log l : write.preceding) { + if (l == this) return true; + } + return false; + } + + @Override + public String toString() { + return String.format("%c: %s (%s, %s), %d - %d", read ? 'R' : 'W', value, threadName, + new SimpleDateFormat("HH:mm:ss,SSS").format(new Date(wallClockTime)), before, after); + } + } +} diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Address.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Address.java index d547a857006b..0a52e8e9ac75 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Address.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Address.java @@ -153,6 +153,7 @@ public boolean equals(Object o) { Address address = (Address) o; + // inhabitants must not be in the comparison since we would end up in infinite recursion if (id != address.id) return false; if (streetNumber != address.streetNumber) return false; if (version != address.version) return false; @@ -160,8 +161,6 @@ public boolean equals(Object o) { return false; if (countryName != null ? !countryName.equals(address.countryName) : address.countryName != null) return false; - if (inhabitants != null ? !inhabitants.equals(address.inhabitants) : address.inhabitants != null) - return false; if (streetName != null ? !streetName.equals(address.streetName) : address.streetName != null) return false; if (zipCode != null ? !zipCode.equals(address.zipCode) : address.zipCode != null) @@ -177,7 +176,6 @@ public int hashCode() { result = 31 * result + (cityName != null ? cityName.hashCode() : 0); result = 31 * result + (countryName != null ? countryName.hashCode() : 0); result = 31 * result + (zipCode != null ? zipCode.hashCode() : 0); - result = 31 * result + (inhabitants != null ? inhabitants.hashCode() : 0); result = 31 * result + id; result = 31 * result + version; return result; diff --git a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Family.java b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Family.java index ebe7f1a8b887..9f323a518457 100644 --- a/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Family.java +++ b/hibernate-infinispan/src/test/java/org/hibernate/test/cache/infinispan/stress/entities/Family.java @@ -7,10 +7,12 @@ package org.hibernate.test.cache.infinispan.stress.entities; +import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; +import javax.persistence.Version; import java.util.HashSet; import java.util.Set; @@ -22,8 +24,9 @@ public final class Family { private int id; private String name; private String secondName; - @OneToMany + @OneToMany(cascade = CascadeType.ALL) private Set members; + @Version private int version; public Family(String name) { @@ -97,10 +100,9 @@ public boolean equals(Object o) { Family family = (Family) o; + // members must not be in the comparison since we would end up in infinite recursive call if (id != family.id) return false; if (version != family.version) return false; - if (members != null ? !members.equals(family.members) : family.members != null) - return false; if (name != null ? !name.equals(family.name) : family.name != null) return false; if (secondName != null ? !secondName.equals(family.secondName) : family.secondName != null) @@ -113,7 +115,6 @@ public boolean equals(Object o) { public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (secondName != null ? secondName.hashCode() : 0); - result = 31 * result + (members != null ? members.hashCode() : 0); result = 31 * result + id; result = 31 * result + version; return result;