diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java
index dca84bbd78e9..eab59166400a 100644
--- a/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java
+++ b/hibernate-core/src/main/java/org/hibernate/action/internal/CollectionAction.java
@@ -12,7 +12,7 @@
import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
import org.hibernate.action.spi.Executable;
import org.hibernate.cache.CacheException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SessionImplementor;
@@ -76,12 +76,14 @@ public final void beforeExecutions() throws CacheException {
// bidirectional association and it is one of the earlier entity actions which actually updates
// the database (this action is responsible for second-level cache invalidation only)
if ( persister.hasCache() ) {
- final CacheKey ck = session.generateCacheKey(
+ final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey(
key,
- persister.getKeyType(),
- persister.getRole()
+ persister,
+ session.getFactory(),
+ session.getTenantIdentifier()
);
- final SoftLock lock = persister.getCacheAccessStrategy().lockItem( ck, null );
+ final SoftLock lock = cache.lockItem( ck, null );
// the old behavior used key as opposed to getKey()
afterTransactionProcess = new CacheCleanupProcess( key, persister, lock );
}
@@ -127,12 +129,14 @@ protected final SessionImplementor getSession() {
protected final void evict() throws CacheException {
if ( persister.hasCache() ) {
- final CacheKey ck = session.generateCacheKey(
+ final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey(
key,
- persister.getKeyType(),
- persister.getRole()
+ persister,
+ session.getFactory(),
+ session.getTenantIdentifier()
);
- persister.getCacheAccessStrategy().remove( ck );
+ cache.remove( ck );
}
}
@@ -169,12 +173,14 @@ private CacheCleanupProcess(Serializable key, CollectionPersister persister, Sof
@Override
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
- final CacheKey ck = session.generateCacheKey(
+ final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey(
key,
- persister.getKeyType(),
- persister.getRole()
+ persister,
+ session.getFactory(),
+ session.getTenantIdentifier()
);
- persister.getCacheAccessStrategy().unlockItem( ck, lock );
+ cache.unlockItem( ck, lock );
}
}
@@ -191,8 +197,3 @@ protected EventSource eventSource() {
}
}
-
-
-
-
-
diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java
index 27f32c00ac8e..2ac9736be879 100644
--- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java
+++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityDeleteAction.java
@@ -10,7 +10,7 @@
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.PersistenceContext;
@@ -84,10 +84,11 @@ public void execute() throws HibernateException {
version = persister.getVersion( instance );
}
- final CacheKey ck;
+ final Object ck;
if ( persister.hasCache() ) {
- ck = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() );
- lock = persister.getCacheAccessStrategy().lockItem( ck, version );
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ ck = cache.generateCacheKey( id, persister, session.getFactory(), session.getTenantIdentifier() );
+ lock = cache.lockItem( ck, version );
}
else {
ck = null;
@@ -184,13 +185,16 @@ private void postCommitDelete(boolean success) {
@Override
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws HibernateException {
- if ( getPersister().hasCache() ) {
- final CacheKey ck = getSession().generateCacheKey(
+ EntityPersister entityPersister = getPersister();
+ if ( entityPersister.hasCache() ) {
+ EntityRegionAccessStrategy cache = entityPersister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey(
getId(),
- getPersister().getIdentifierType(),
- getPersister().getRootEntityName()
+ entityPersister,
+ session.getFactory(),
+ session.getTenantIdentifier()
);
- getPersister().getCacheAccessStrategy().unlockItem( ck, lock );
+ cache.unlockItem( ck, lock );
}
postCommitDelete( success );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java
index c927873a69d2..8b64f155c3b0 100644
--- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java
+++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityInsertAction.java
@@ -10,11 +10,13 @@
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey;
+import org.hibernate.engine.spi.PersistenceContext;
+import org.hibernate.engine.spi.SessionEventListenerManager;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
@@ -85,8 +87,8 @@ public void execute() throws HibernateException {
if ( !veto ) {
persister.insert( id, getState(), instance, session );
-
- final EntityEntry entry = session.getPersistenceContext().getEntry( instance );
+ PersistenceContext persistenceContext = session.getPersistenceContext();
+ final EntityEntry entry = persistenceContext.getEntry( instance );
if ( entry == null ) {
throw new AssertionFailure( "possible non-threadsafe access to session" );
}
@@ -101,10 +103,10 @@ public void execute() throws HibernateException {
entry.postUpdate( instance, getState(), version );
}
- getSession().getPersistenceContext().registerInsertedKey( getPersister(), getId() );
+ persistenceContext.registerInsertedKey( persister, getId() );
}
- final SessionFactoryImplementor factory = getSession().getFactory();
+ final SessionFactoryImplementor factory = session.getFactory();
if ( isCachePutEnabled( persister, session ) ) {
final CacheEntry ce = persister.buildCacheEntry(
@@ -114,12 +116,13 @@ public void execute() throws HibernateException {
session
);
cacheEntry = persister.getCacheEntryStructure().structure( ce );
- final CacheKey ck = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() );
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() );
final boolean put = cacheInsert( persister, ck );
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
- factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
+ factory.getStatisticsImplementor().secondLevelCachePut( cache.getRegion().getName() );
}
}
@@ -134,7 +137,7 @@ public void execute() throws HibernateException {
markExecuted();
}
- private boolean cacheInsert(EntityPersister persister, CacheKey ck) {
+ private boolean cacheInsert(EntityPersister persister, Object ck) {
try {
getSession().getEventListenerManager().cachePutStart();
return persister.getCacheAccessStrategy().insert( ck, cacheEntry, version );
@@ -207,24 +210,27 @@ private boolean preInsert() {
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws HibernateException {
final EntityPersister persister = getPersister();
if ( success && isCachePutEnabled( persister, getSession() ) ) {
- final CacheKey ck = getSession().generateCacheKey( getId(), persister.getIdentifierType(), persister.getRootEntityName() );
- final boolean put = cacheAfterInsert( persister, ck );
-
- if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
- getSession().getFactory().getStatisticsImplementor()
- .secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ SessionFactoryImplementor sessionFactoryImplementor = session.getFactory();
+ final Object ck = cache.generateCacheKey( getId(), persister, sessionFactoryImplementor, session.getTenantIdentifier() );
+ final boolean put = cacheAfterInsert( cache, ck );
+
+ if ( put && sessionFactoryImplementor.getStatistics().isStatisticsEnabled() ) {
+ sessionFactoryImplementor.getStatisticsImplementor()
+ .secondLevelCachePut( cache.getRegion().getName() );
}
}
postCommitInsert( success );
}
- private boolean cacheAfterInsert(EntityPersister persister, CacheKey ck) {
+ private boolean cacheAfterInsert(EntityRegionAccessStrategy cache, Object ck) {
+ final SessionEventListenerManager eventListenerManager = getSession().getEventListenerManager();
try {
- getSession().getEventListenerManager().cachePutStart();
- return persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version );
+ eventListenerManager.cachePutStart();
+ return cache.afterInsert( ck, cacheEntry, version );
}
finally {
- getSession().getEventListenerManager().cachePutEnd();
+ eventListenerManager.cachePutEnd();
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java
index 343d477db5ae..ea449655faa2 100644
--- a/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java
+++ b/hibernate-core/src/main/java/org/hibernate/action/internal/EntityUpdateAction.java
@@ -11,12 +11,13 @@
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.cache.CacheException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.CachedNaturalIdValueSource;
import org.hibernate.engine.spi.EntityEntry;
+import org.hibernate.engine.spi.SessionEventListenerManager;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
@@ -116,7 +117,7 @@ public void execute() throws HibernateException {
final boolean veto = preUpdate();
- final SessionFactoryImplementor factory = getSession().getFactory();
+ final SessionFactoryImplementor factory = session.getFactory();
Object previousVersion = this.previousVersion;
if ( persister.isVersionPropertyGenerated() ) {
// we need to grab the version value from the entity, otherwise
@@ -125,14 +126,16 @@ public void execute() throws HibernateException {
previousVersion = persister.getVersion( instance );
}
- final CacheKey ck;
+ final Object ck;
if ( persister.hasCache() ) {
- ck = session.generateCacheKey(
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ ck = cache.generateCacheKey(
id,
- persister.getIdentifierType(),
- persister.getRootEntityName()
+ persister,
+ factory,
+ session.getTenantIdentifier()
);
- lock = persister.getCacheAccessStrategy().lockItem( ck, previousVersion );
+ lock = cache.lockItem( ck, previousVersion );
}
else {
ck = null;
@@ -152,7 +155,7 @@ public void execute() throws HibernateException {
);
}
- final EntityEntry entry = getSession().getPersistenceContext().getEntry( instance );
+ final EntityEntry entry = session.getPersistenceContext().getEntry( instance );
if ( entry == null ) {
throw new AssertionFailure( "possible nonthreadsafe access to session" );
}
@@ -212,7 +215,7 @@ public void execute() throws HibernateException {
}
}
- private boolean cacheUpdate(EntityPersister persister, Object previousVersion, CacheKey ck) {
+ private boolean cacheUpdate(EntityPersister persister, Object previousVersion, Object ck) {
try {
getSession().getEventListenerManager().cachePutStart();
return persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion );
@@ -307,34 +310,37 @@ protected boolean hasPostCommitEventListeners() {
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws CacheException {
final EntityPersister persister = getPersister();
if ( persister.hasCache() ) {
-
- final CacheKey ck = getSession().generateCacheKey(
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey(
getId(),
- persister.getIdentifierType(),
- persister.getRootEntityName()
+ persister,
+ session.getFactory(),
+ session.getTenantIdentifier()
+
);
-
+
if ( success && cacheEntry!=null /*!persister.isCacheInvalidationRequired()*/ ) {
- final boolean put = cacheAfterUpdate( persister, ck );
+ final boolean put = cacheAfterUpdate( cache, ck );
if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
- getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
+ getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( cache.getRegion().getName() );
}
}
else {
- persister.getCacheAccessStrategy().unlockItem( ck, lock );
+ cache.unlockItem( ck, lock );
}
}
postCommitUpdate( success );
}
- private boolean cacheAfterUpdate(EntityPersister persister, CacheKey ck) {
+ private boolean cacheAfterUpdate(EntityRegionAccessStrategy cache, Object ck) {
+ SessionEventListenerManager eventListenerManager = getSession().getEventListenerManager();
try {
- getSession().getEventListenerManager().cachePutStart();
- return persister.getCacheAccessStrategy().afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock );
+ eventListenerManager.cachePutStart();
+ return cache.afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock );
}
finally {
- getSession().getEventListenerManager().cachePutEnd();
+ eventListenerManager.cachePutEnd();
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/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/CollectionCacheInvalidator.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java
index 6e52e1546609..773ce619e63f 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CollectionCacheInvalidator.java
@@ -10,7 +10,7 @@
import java.util.Set;
import org.hibernate.boot.Metadata;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventSource;
@@ -136,8 +136,16 @@ private void evictCache(Object entity, EntityPersister persister, EventSource se
}
private void evict(Serializable id, CollectionPersister collectionPersister, EventSource session) {
- LOG.debug( "Evict CollectionRegion " + collectionPersister.getRole() + " for id " + id );
- CacheKey key = session.generateCacheKey( id, collectionPersister.getKeyType(), collectionPersister.getRole() );
- collectionPersister.getCacheAccessStrategy().evict( key );
+ if ( LOG.isDebugEnabled() ) {
+ LOG.debug( "Evict CollectionRegion " + collectionPersister.getRole() + " for id " + id );
+ }
+ CollectionRegionAccessStrategy cache = collectionPersister.getCacheAccessStrategy();
+ Object key = cache.generateCacheKey(
+ id,
+ collectionPersister,
+ session.getFactory(),
+ session.getTenantIdentifier()
+ );
+ cache.evict( key );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java
new file mode 100644
index 000000000000..15aa4c6ce43d
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/DefaultCacheKeysFactory.java
@@ -0,0 +1,98 @@
+/*
+ * 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;
+
+/**
+ * Second level cache providers now have the option to use custom key implementations.
+ * This was done as the default key implementation is very generic and is quite
+ * a large object to allocate in large quantities at runtime.
+ * In some extreme cases, for example when the hit ratio is very low, this was making the efficiency
+ * penalty vs its benefits tradeoff questionable.
+ *
+ * Depending on configuration settings there might be opportunities to
+ * use simpler key implementations, for example when multi-tenancy is not being used to
+ * avoid the tenant identifier, or when a cache instance is entirely dedicated to a single type
+ * to use the primary id only, skipping the role or entity name.
+ *
+ * Even with multiple types sharing the same cache, their identifiers could be of the same
+ * {@link org.hibernate.type.Type}; in this case the cache container could
+ * use a single type reference to implement a custom equality function without having
+ * to look it up on each equality check: that's a small optimisation but the
+ * equality function is often invoked extremely frequently.
+ *
+ * Another reason is to make it more convenient to implement custom serialization protocols when the
+ * implementation supports clustering.
+ *
+ * @see org.hibernate.type.Type#getHashCode(Object, SessionFactoryImplementor)
+ * @see org.hibernate.type.Type#isEqual(Object, Object)
+ * @author Sanne Grinovero
+ * @since 5.0
+ */
+public class DefaultCacheKeysFactory {
+
+ public static Object createCollectionKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return new OldCacheKeyImplementation( id, persister.getKeyType(), persister.getRole(), tenantIdentifier, factory );
+ }
+
+ public static Object createEntityKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return new OldCacheKeyImplementation( id, persister.getIdentifierType(), persister.getRootEntityName(), tenantIdentifier, factory );
+ }
+
+ public static Object createNaturalIdKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
+ return new OldNaturalIdCacheKey( naturalIdValues, persister.getPropertyTypes(), persister.getNaturalIdentifierProperties(), persister.getRootEntityName(), 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();
+ }
+
+ 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/spi/CacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java
old mode 100755
new mode 100644
similarity index 75%
rename from hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java
rename to hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java
index f33d311af7ca..20098a1d8956
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/CacheKey.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldCacheKeyImplementation.java
@@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
-package org.hibernate.cache.spi;
+package org.hibernate.cache.internal;
import java.io.Serializable;
@@ -16,11 +16,15 @@
* Allows multiple entity classes / collection roles to be stored in the same cache region. Also allows for composite
* keys which do not properly implement equals()/hashCode().
*
+ * This was named org.hibernate.cache.spi.CacheKey in Hibernate until version 5.
+ * Temporarily maintained as a reference while all components catch up with the refactoring to the caching interfaces.
+ *
* @author Gavin King
* @author Steve Ebersole
*/
-public class CacheKey implements Serializable {
- private final Serializable key;
+@Deprecated
+final class OldCacheKeyImplementation implements Serializable {
+ private final Object id;
private final Type type;
private final String entityOrRoleName;
private final String tenantId;
@@ -37,13 +41,13 @@ public class CacheKey implements Serializable {
* @param tenantId The tenant identifier associated this data.
* @param factory The session factory for which we are caching
*/
- public CacheKey(
- final Serializable id,
+ OldCacheKeyImplementation(
+ final Object id,
final Type type,
final String entityOrRoleName,
final String tenantId,
final SessionFactoryImplementor factory) {
- this.key = id;
+ this.id = id;
this.type = type;
this.entityOrRoleName = entityOrRoleName;
this.tenantId = tenantId;
@@ -51,21 +55,13 @@ public CacheKey(
}
private int calculateHashCode(Type type, SessionFactoryImplementor factory) {
- int result = type.getHashCode( key, factory );
+ int result = type.getHashCode(id, factory );
result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0);
return result;
}
- public Serializable getKey() {
- return key;
- }
-
- public String getEntityOrRoleName() {
- return entityOrRoleName;
- }
-
- public String getTenantId() {
- return tenantId;
+ public Object getId() {
+ return id;
}
@Override
@@ -76,13 +72,13 @@ public boolean equals(Object other) {
if ( this == other ) {
return true;
}
- if ( hashCode != other.hashCode() || !( other instanceof CacheKey ) ) {
+ if ( hashCode != other.hashCode() || !( other instanceof OldCacheKeyImplementation ) ) {
//hashCode is part of this check since it is pre-calculated and hash must match for equals to be true
return false;
}
- final CacheKey that = (CacheKey) other;
+ final OldCacheKeyImplementation that = (OldCacheKeyImplementation) other;
return EqualsHelper.equals( entityOrRoleName, that.entityOrRoleName )
- && type.isEqual( key, that.key )
+ && type.isEqual(id, that.id)
&& EqualsHelper.equals( tenantId, that.tenantId );
}
@@ -94,6 +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/spi/NaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java
similarity index 85%
rename from hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java
rename to hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java
index eb1e2a70665d..e0aa87e596b8 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/NaturalIdCacheKey.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/OldNaturalIdCacheKey.java
@@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
-package org.hibernate.cache.spi;
+package org.hibernate.cache.internal;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -15,17 +15,20 @@
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
*/
-public class NaturalIdCacheKey implements Serializable {
+@Deprecated
+public class OldNaturalIdCacheKey implements Serializable {
private final Serializable[] naturalIdValues;
private final String entityName;
private final String tenantId;
@@ -35,25 +38,22 @@ public class NaturalIdCacheKey implements Serializable {
/**
* Construct a new key for a caching natural identifier resolutions into the second level cache.
- * Note that an entity name should always be the root entity name, not a subclass entity name.
- *
* @param naturalIdValues The naturalIdValues associated with the cached data
- * @param persister The persister for the entity
+ * @param propertyTypes
+ * @param naturalIdPropertyIndexes
* @param session The originating session
*/
- public NaturalIdCacheKey(
+ 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;
@@ -88,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 ) {
@@ -137,12 +137,12 @@ public boolean equals(Object o) {
return true;
}
- if ( hashCode != o.hashCode() || !( o instanceof NaturalIdCacheKey ) ) {
+ if ( hashCode != o.hashCode() || !( o instanceof OldNaturalIdCacheKey ) ) {
//hashCode is part of this check since it is pre-calculated and hash must match for equals to be true
return false;
}
- final NaturalIdCacheKey other = (NaturalIdCacheKey) o;
+ final OldNaturalIdCacheKey other = (OldNaturalIdCacheKey) o;
return EqualsHelper.equals( entityName, other.entityName )
&& EqualsHelper.equals( tenantId, other.tenantId )
&& Arrays.deepEquals( this.naturalIdValues, other.naturalIdValues );
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/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/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java
index 7bf21b364c82..621dc3c992e0 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/CollectionRegionAccessStrategy.java
@@ -7,6 +7,8 @@
package org.hibernate.cache.spi.access;
import org.hibernate.cache.spi.CollectionRegion;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
/**
* Contract for managing transactional and concurrent access to cached collection
@@ -23,6 +25,25 @@
*/
public interface CollectionRegionAccessStrategy extends RegionAccessStrategy {
+ /**
+ * To create instances of CollectionCacheKey for this region, Hibernate will invoke this method
+ * exclusively so that generated implementations can generate optimised keys.
+ * @param id the primary identifier of the Collection
+ * @param persister the persister for the type for which a key is being generated
+ * @param factory a reference to the current SessionFactory
+ * @param tenantIdentifier the tenant id, or null if multi-tenancy is not being used.
+ * @return a key which can be used to identify this collection on this same region
+ */
+ public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier);
+
+ /**
+ * Performs reverse operation to {@link #generateCacheKey(Object, CollectionPersister, SessionFactoryImplementor, String)}
+ *
+ * @param cacheKey key previously returned from {@link #generateCacheKey(Object, CollectionPersister, SessionFactoryImplementor, String)}
+ * @return original key passed to {@link #generateCacheKey(Object, CollectionPersister, SessionFactoryImplementor, String)}
+ */
+ public Object getCacheKeyId(Object cacheKey);
+
/**
* Get the wrapped collection cache region
*
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java
index b63c85fa33c7..32c5382b94b2 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/EntityRegionAccessStrategy.java
@@ -8,6 +8,8 @@
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Contract for managing transactional and concurrent access to cached entity
@@ -25,7 +27,26 @@
* @author Gavin King
* @author Steve Ebersole
*/
-public interface EntityRegionAccessStrategy extends RegionAccessStrategy{
+public interface EntityRegionAccessStrategy extends RegionAccessStrategy {
+
+ /**
+ * To create instances of EntityCacheKey for this region, Hibernate will invoke this method
+ * exclusively so that generated implementations can generate optimised keys.
+ * @param id the primary identifier of the entity
+ * @param persister the persister for the type for which a key is being generated
+ * @param factory a reference to the current SessionFactory
+ * @param tenantIdentifier the tenant id, or null if multi-tenancy is not being used.
+ * @return a key which can be used to identify this entity on this same region
+ */
+ public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier);
+
+ /**
+ * Performs reverse operation to {@link #generateCacheKey(Object, EntityPersister, SessionFactoryImplementor, String)}
+ *
+ * @param cacheKey key previously returned from {@link #generateCacheKey(Object, EntityPersister, SessionFactoryImplementor, String)}
+ * @return original id passed to {@link #generateCacheKey(Object, EntityPersister, SessionFactoryImplementor, String)}
+ */
+ public Object getCacheKeyId(Object cacheKey);
/**
* Get the wrapped entity cache region
@@ -43,7 +64,7 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{
* @param value The item
* @param version The item's version value
* @return Were the contents of the cache actual changed by this operation?
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/
public boolean insert(Object key, Object value, Object version) throws CacheException;
@@ -56,7 +77,7 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{
* @param value The item
* @param version The item's version value
* @return Were the contents of the cache actual changed by this operation?
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/
public boolean afterInsert(Object key, Object value, Object version) throws CacheException;
@@ -70,7 +91,7 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{
* @param currentVersion The item's current version value
* @param previousVersion The item's previous version value
* @return Were the contents of the cache actual changed by this operation?
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException;
@@ -85,7 +106,7 @@ public interface EntityRegionAccessStrategy extends RegionAccessStrategy{
* @param previousVersion The item's previous version value
* @param lock The lock previously obtained from {@link #lockItem}
* @return Were the contents of the cache actual changed by this operation?
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java
index 83e4c8871a7c..bbf60eb8c9a3 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/NaturalIdRegionAccessStrategy.java
@@ -8,6 +8,8 @@
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.NaturalIdRegion;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Contract for managing transactional and concurrent access to cached naturalId
@@ -36,6 +38,24 @@
*/
public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy {
+ /**
+ * To create instances of NaturalIdCacheKey for this region, Hibernate will invoke this method
+ * exclusively so that generated implementations can generate optimised keys.
+ * @param naturalIdValues the sequence of values which unequivocally identifies a cached element on this region
+ * @param persister the persister of the element being cached
+ * @param session
+ * @return a key which can be used to identify this an element unequivocally on this same region
+ */
+ public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session);
+
+ /**
+ * Performs reverse operation to {@link #generateCacheKey(Object[], EntityPersister, SessionImplementor)}, returning
+ * the original naturalIdValues.
+ * @param cacheKey key returned from {@link #generateCacheKey(Object[], EntityPersister, SessionImplementor)}
+ * @return the sequence of values which unequivocally identifies a cached element on this region
+ */
+ public Object[] getNaturalIdValues(Object cacheKey);
+
/**
* Get the wrapped naturalId cache region
*
@@ -51,7 +71,7 @@ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy {
* @param key The item key
* @param value The item
* @return Were the contents of the cache actual changed by this operation?
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/
public boolean insert(Object key, Object value) throws CacheException;
@@ -63,7 +83,7 @@ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy {
* @param key The item key
* @param value The item
* @return Were the contents of the cache actual changed by this operation?
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/
public boolean afterInsert(Object key, Object value) throws CacheException;
@@ -75,7 +95,7 @@ public interface NaturalIdRegionAccessStrategy extends RegionAccessStrategy {
* @param key The item key
* @param value The item
* @return Were the contents of the cache actual changed by this operation?
- * @throws CacheException Propogated from underlying {@link org.hibernate.cache.spi.Region}
+ * @throws CacheException Propagated from underlying {@link org.hibernate.cache.spi.Region}
*/
public boolean update(Object key, Object value) throws CacheException;
diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java
index a06b22c4be6d..42e4b8d71095 100644
--- a/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java
+++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/access/RegionAccessStrategy.java
@@ -6,6 +6,7 @@
*/
package org.hibernate.cache.spi.access;
+
import org.hibernate.cache.CacheException;
/**
@@ -14,6 +15,7 @@
* @author Gail Badner
*/
public interface RegionAccessStrategy {
+
/**
* Attempt to retrieve an object from the cache. Mainly used in attempting
* to resolve entities/collections from the second level cache.
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java
index 884b4736fe2c..6eb0ff52dad7 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java
@@ -8,45 +8,33 @@
import java.io.Serializable;
-import org.hibernate.cache.spi.CacheKey;
-import org.hibernate.cache.spi.NaturalIdCacheKey;
-import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.RegionAccessStrategy;
+import org.hibernate.engine.spi.SessionEventListenerManager;
import org.hibernate.engine.spi.SessionImplementor;
/**
* @author Steve Ebersole
+ * @author Sanne Grinovero
*/
public final class CacheHelper {
+
private CacheHelper() {
}
public static Serializable fromSharedCache(
- SessionImplementor session,
- NaturalIdCacheKey cacheKey,
- NaturalIdRegionAccessStrategy cacheAccessStrategy) {
- return fromSharedCache( session, (Object) cacheKey, cacheAccessStrategy );
- }
-
- private static Serializable fromSharedCache(
SessionImplementor session,
Object cacheKey,
RegionAccessStrategy cacheAccessStrategy) {
+ final SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
Serializable cachedValue = null;
+ eventListenerManager.cacheGetStart();
try {
- session.getEventListenerManager().cacheGetStart();
cachedValue = (Serializable) cacheAccessStrategy.get( cacheKey, session.getTimestamp() );
}
finally {
- session.getEventListenerManager().cacheGetEnd( cachedValue != null );
+ eventListenerManager.cacheGetEnd( cachedValue != null );
}
return cachedValue;
}
- public static Serializable fromSharedCache(
- SessionImplementor session,
- CacheKey cacheKey,
- RegionAccessStrategy cacheAccessStrategy) {
- return fromSharedCache( session, (Object) cacheKey, cacheAccessStrategy );
- }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java
index f3a2be5ae78d..0ef204f9c841 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/NaturalIdXrefDelegate.java
@@ -15,7 +15,6 @@
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.AssertionFailure;
-import org.hibernate.cache.spi.NaturalIdCacheKey;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@@ -110,12 +109,12 @@ public Object[] removeNaturalIdCrossReference(EntityPersister persister, Seriali
if ( persister.hasNaturalIdCache() ) {
final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister
.getNaturalIdCacheAccessStrategy();
- final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session() );
+ final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() );
naturalIdCacheAccessStrategy.evict( naturalIdCacheKey );
if ( sessionCachedNaturalIdValues != null
&& !Arrays.equals( sessionCachedNaturalIdValues, naturalIdValues ) ) {
- final NaturalIdCacheKey sessionNaturalIdCacheKey = new NaturalIdCacheKey( sessionCachedNaturalIdValues, persister, session() );
+ final Object sessionNaturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( sessionCachedNaturalIdValues, persister, session() );
naturalIdCacheAccessStrategy.evict( sessionNaturalIdCacheKey );
}
}
@@ -239,9 +238,9 @@ public Serializable findCachedNaturalIdResolution(EntityPersister persister, Obj
}
// Try resolution from second-level cache
- final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session() );
-
final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy();
+ final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session() );
+
pk = CacheHelper.fromSharedCache( session(), naturalIdCacheKey, naturalIdCacheAccessStrategy );
// Found in second-level cache, store in session cache
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java
index ad511753d424..becb76f8b4a8 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/StatefulPersistenceContext.java
@@ -31,7 +31,6 @@
import org.hibernate.PersistentObjectException;
import org.hibernate.TransientObjectException;
import org.hibernate.action.spi.AfterTransactionCompletionProcess;
-import org.hibernate.cache.spi.NaturalIdCacheKey;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.collection.spi.PersistentCollection;
@@ -1738,7 +1737,7 @@ private void managedSharedCacheEntries(
Object[] previousNaturalIdValues,
CachedNaturalIdValueSource source) {
final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy();
- final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session );
+ final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session );
final SessionFactoryImplementor factory = session.getFactory();
@@ -1793,7 +1792,7 @@ public void doAfterTransactionCompletion(boolean success, SessionImplementor ses
break;
}
case UPDATE: {
- final NaturalIdCacheKey previousCacheKey = new NaturalIdCacheKey( previousNaturalIdValues, persister, session );
+ final Object previousCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( previousNaturalIdValues, persister, session );
if ( naturalIdCacheKey.equals( previousCacheKey ) ) {
// prevent identical re-caching, solves HHH-7309
return;
@@ -1877,7 +1876,7 @@ public void removeSharedNaturalIdCrossReference(EntityPersister persister, Seria
persister = locateProperPersister( persister );
final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy = persister.getNaturalIdCacheAccessStrategy();
- final NaturalIdCacheKey naturalIdCacheKey = new NaturalIdCacheKey( naturalIdValues, persister, session );
+ final Object naturalIdCacheKey = naturalIdCacheAccessStrategy.generateCacheKey( naturalIdValues, persister, session );
naturalIdCacheAccessStrategy.evict( naturalIdCacheKey );
// if ( sessionCachedNaturalIdValues != null
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/TwoPhaseLoad.java
index 4781c6838193..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,11 +13,12 @@
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
+import org.hibernate.engine.spi.SessionEventListenerManager;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
@@ -182,7 +183,8 @@ private static void doInitializeEntity(
final Object version = Versioning.getVersion( hydratedState, persister );
final CacheEntry entry = persister.buildCacheEntry( entity, hydratedState, version, session );
- final CacheKey cacheKey = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() );
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object cacheKey = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() );
// explicit handling of caching for rows just inserted and then somehow forced to be read
// from the database *within the same transaction*. usually this is done by
@@ -191,7 +193,7 @@ private static void doInitializeEntity(
//
// we need to be careful not to clobber the lock here in the cache so that it can be rolled back if need be
if ( session.getPersistenceContext().wasInsertedDuringTransaction( persister, id ) ) {
- persister.getCacheAccessStrategy().update(
+ cache.update(
cacheKey,
persister.getCacheEntryStructure().structure( entry ),
version,
@@ -199,9 +201,10 @@ private static void doInitializeEntity(
);
}
else {
+ final SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
try {
- session.getEventListenerManager().cachePutStart();
- final boolean put = persister.getCacheAccessStrategy().putFromLoad(
+ eventListenerManager.cachePutStart();
+ final boolean put = cache.putFromLoad(
cacheKey,
persister.getCacheEntryStructure().structure( entry ),
session.getTimestamp(),
@@ -210,11 +213,11 @@ private static void doInitializeEntity(
);
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
- factory.getStatisticsImplementor().secondLevelCachePut( persister.getCacheAccessStrategy().getRegion().getName() );
+ factory.getStatisticsImplementor().secondLevelCachePut( cache.getRegion().getName() );
}
}
finally {
- session.getEventListenerManager().cachePutEnd();
+ eventListenerManager.cachePutEnd();
}
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java
index 0e4399f82cf6..af8624032a4f 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/loading/internal/CollectionLoadContext.java
@@ -17,7 +17,7 @@
import org.hibernate.CacheMode;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.entry.CollectionCacheEntry;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry;
@@ -332,7 +332,13 @@ private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersiste
}
final CollectionCacheEntry entry = new CollectionCacheEntry( lce.getCollection(), persister );
- final CacheKey cacheKey = session.generateCacheKey( lce.getKey(), persister.getKeyType(), persister.getRole() );
+ final CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object cacheKey = cache.generateCacheKey(
+ lce.getKey(),
+ persister,
+ session.getFactory(),
+ session.getTenantIdentifier()
+ );
boolean isPutFromLoad = true;
if ( persister.getElementType().isAssociationType() ) {
@@ -349,7 +355,7 @@ private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersiste
if (isPutFromLoad) {
try {
session.getEventListenerManager().cachePutStart();
- final boolean put = persister.getCacheAccessStrategy().putFromLoad(
+ final boolean put = cache.putFromLoad(
cacheKey,
persister.getCacheEntryStructure().structure( entry ),
session.getTimestamp(),
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/BatchFetchQueue.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/BatchFetchQueue.java
index 0a721b4c301b..b28669d43be5 100755
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/BatchFetchQueue.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/BatchFetchQueue.java
@@ -14,7 +14,8 @@
import java.util.Map.Entry;
import org.hibernate.EntityMode;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.CacheHelper;
import org.hibernate.internal.CoreLogging;
@@ -201,13 +202,16 @@ public Serializable[] getEntityBatch(
}
private boolean isCached(EntityKey entityKey, EntityPersister persister) {
+ final SessionImplementor session = context.getSession();
if ( context.getSession().getCacheMode().isGetEnabled() && persister.hasCache() ) {
- final CacheKey key = context.getSession().generateCacheKey(
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object key = cache.generateCacheKey(
entityKey.getIdentifier(),
- persister.getIdentifierType(),
- persister.getRootEntityName()
+ persister,
+ session.getFactory(),
+ session.getTenantIdentifier()
);
- return CacheHelper.fromSharedCache( context.getSession(), key, persister.getCacheAccessStrategy() ) != null;
+ return CacheHelper.fromSharedCache( session, key, cache ) != null;
}
return false;
}
@@ -314,14 +318,18 @@ else if ( !isCached( ce.getLoadedKey(), collectionPersister ) ) {
}
private boolean isCached(Serializable collectionKey, CollectionPersister persister) {
- if ( context.getSession().getCacheMode().isGetEnabled() && persister.hasCache() ) {
- CacheKey cacheKey = context.getSession().generateCacheKey(
+ SessionImplementor session = context.getSession();
+ if ( session.getCacheMode().isGetEnabled() && persister.hasCache() ) {
+ CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ Object cacheKey = cache.generateCacheKey(
collectionKey,
- persister.getKeyType(),
- persister.getRole()
+ persister,
+ session.getFactory(),
+ session.getTenantIdentifier()
);
- return CacheHelper.fromSharedCache( context.getSession(), cacheKey, persister.getCacheAccessStrategy() ) != null;
+ return CacheHelper.fromSharedCache( session, cacheKey, cache ) != null;
}
return false;
}
+
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java
index 68d2e2cb0b7d..5bbe3c475867 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java
@@ -35,7 +35,6 @@
import org.hibernate.Transaction;
import org.hibernate.TypeHelper;
import org.hibernate.UnknownProfileException;
-import org.hibernate.cache.spi.CacheKey;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
@@ -47,7 +46,6 @@
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.resource.transaction.TransactionCoordinator;
import org.hibernate.stat.SessionStatistics;
-import org.hibernate.type.Type;
/**
* This class is meant to be extended.
@@ -97,11 +95,6 @@ public EntityKey generateEntityKey(Serializable id, EntityPersister persister) {
return sessionImplementor.generateEntityKey( id, persister );
}
- @Override
- public CacheKey generateCacheKey(Serializable id, Type type, String entityOrRoleName) {
- return sessionImplementor.generateCacheKey( id, type, entityOrRoleName );
- }
-
@Override
public Interceptor getInterceptor() {
return sessionImplementor.getInterceptor();
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java
index 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/engine/spi/SessionImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java
index fe1c164f7151..9ed6dfa3b9a0 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java
@@ -20,7 +20,6 @@
import org.hibernate.SQLQuery;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
-import org.hibernate.cache.spi.CacheKey;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
@@ -64,17 +63,6 @@ public interface SessionImplementor extends Serializable, LobCreationContext {
*/
EntityKey generateEntityKey(Serializable id, EntityPersister persister);
- /**
- * Hide the changing requirements of cache key creation.
- *
- * @param id The entity identifier or collection key.
- * @param type The type
- * @param entityOrRoleName The entity name or collection role.
- *
- * @return The cache key
- */
- CacheKey generateCacheKey(Serializable id, final Type type, final String entityOrRoleName);
-
/**
* Retrieves the interceptor currently in use by this event source.
*
diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java
index 1d8a5851e3d1..66169048d299 100644
--- a/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java
+++ b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractLockUpgradeEventListener.java
@@ -9,7 +9,7 @@
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.ObjectDeletedException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.Status;
@@ -17,7 +17,6 @@
import org.hibernate.internal.CoreLogging;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
-
import org.jboss.logging.Logger;
/**
@@ -62,18 +61,16 @@ protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOpt
);
}
- final SoftLock lock;
- final CacheKey ck;
- if ( persister.hasCache() ) {
- ck = source.generateCacheKey( entry.getId(), persister.getIdentifierType(), persister.getRootEntityName() );
- lock = persister.getCacheAccessStrategy().lockItem( ck, entry.getVersion() );
- }
- else {
- ck = null;
- lock = null;
- }
-
+ final boolean cachingEnabled = persister.hasCache();
+ SoftLock lock = null;
+ Object ck = null;
try {
+ if ( cachingEnabled ) {
+ EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ ck = cache.generateCacheKey( entry.getId(), persister, source.getFactory(), source.getTenantIdentifier() );
+ lock = cache.lockItem( ck, entry.getVersion() );
+ }
+
if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE ) {
// todo : should we check the current isolation mode explicitly?
Object nextVersion = persister.forceVersionIncrement(
@@ -89,7 +86,7 @@ protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOpt
finally {
// the database now holds a lock + the object is flushed from the cache,
// so release the soft lock
- if ( persister.hasCache() ) {
+ if ( cachingEnabled ) {
persister.getCacheAccessStrategy().unlockItem( ck, lock );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java
index 38cc1b518b5e..2118ecd20bc6 100755
--- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java
+++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultInitializeCollectionEventListener.java
@@ -9,7 +9,7 @@
import java.io.Serializable;
import org.hibernate.HibernateException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.entry.CollectionCacheEntry;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.CacheHelper;
@@ -116,17 +116,18 @@ private boolean initializeCollectionFromCache(
}
final SessionFactoryImplementor factory = source.getFactory();
- final CacheKey ck = source.generateCacheKey( id, persister.getKeyType(), persister.getRole() );
+ final CollectionRegionAccessStrategy cacheAccessStrategy = persister.getCacheAccessStrategy();
+ final Object ck = cacheAccessStrategy.generateCacheKey( id, persister, factory, source.getTenantIdentifier() );
final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() );
if ( factory.getStatistics().isStatisticsEnabled() ) {
if ( ce == null ) {
factory.getStatisticsImplementor()
- .secondLevelCacheMiss( persister.getCacheAccessStrategy().getRegion().getName() );
+ .secondLevelCacheMiss( cacheAccessStrategy.getRegion().getName() );
}
else {
factory.getStatisticsImplementor()
- .secondLevelCacheHit( persister.getCacheAccessStrategy().getRegion().getName() );
+ .secondLevelCacheHit( cacheAccessStrategy.getRegion().getName() );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java
index 11d4984761e9..135ea67787e0 100644
--- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java
+++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java
@@ -14,7 +14,7 @@
import org.hibernate.PersistentObjectException;
import org.hibernate.TypeMismatchException;
import org.hibernate.WrongClassException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl;
@@ -357,12 +357,14 @@ protected Object lockAndLoad(
final LoadEventListener.LoadType options,
final SessionImplementor source) {
SoftLock lock = null;
- final CacheKey ck;
+ final Object ck;
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
if ( persister.hasCache() ) {
- ck = source.generateCacheKey(
+ ck = cache.generateCacheKey(
event.getEntityId(),
- persister.getIdentifierType(),
- persister.getRootEntityName()
+ persister,
+ source.getFactory(),
+ source.getTenantIdentifier()
);
lock = persister.getCacheAccessStrategy().lockItem( ck, null );
}
@@ -376,7 +378,7 @@ protected Object lockAndLoad(
}
finally {
if ( persister.hasCache() ) {
- persister.getCacheAccessStrategy().unlockItem( ck, lock );
+ cache.unlockItem( ck, lock );
}
}
@@ -572,22 +574,24 @@ protected Object loadFromSecondLevelCache(
}
final SessionFactoryImplementor factory = source.getFactory();
- final CacheKey ck = source.generateCacheKey(
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey(
event.getEntityId(),
- persister.getIdentifierType(),
- persister.getRootEntityName()
+ persister,
+ factory,
+ source.getTenantIdentifier()
);
final Object ce = CacheHelper.fromSharedCache( source, ck, persister.getCacheAccessStrategy() );
if ( factory.getStatistics().isStatisticsEnabled() ) {
if ( ce == null ) {
factory.getStatisticsImplementor().secondLevelCacheMiss(
- persister.getCacheAccessStrategy().getRegion().getName()
+ cache.getRegion().getName()
);
}
else {
factory.getStatisticsImplementor().secondLevelCacheHit(
- persister.getCacheAccessStrategy().getRegion().getName()
+ cache.getRegion().getName()
);
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultRefreshEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultRefreshEventListener.java
index fc01c483681b..6ca71fe98da9 100644
--- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultRefreshEventListener.java
+++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultRefreshEventListener.java
@@ -13,7 +13,7 @@
import org.hibernate.HibernateException;
import org.hibernate.PersistentObjectException;
import org.hibernate.UnresolvableObjectException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.engine.internal.Cascade;
import org.hibernate.engine.internal.CascadePoint;
import org.hibernate.engine.spi.CascadingActions;
@@ -136,12 +136,14 @@ public void onRefresh(RefreshEvent event, Map refreshedAlready) {
}
if ( persister.hasCache() ) {
- final CacheKey ck = source.generateCacheKey(
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ Object ck = cache.generateCacheKey(
id,
- persister.getIdentifierType(),
- persister.getRootEntityName()
+ persister,
+ source.getFactory(),
+ source.getTenantIdentifier()
);
- persister.getCacheAccessStrategy().evict( ck );
+ cache.evict( ck );
}
evictCachedCollections( persister, id, source.getFactory() );
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java
index cc330e1f5aa8..96131d991c99 100755
--- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSessionImpl.java
@@ -26,7 +26,6 @@
import org.hibernate.SharedSessionContract;
import org.hibernate.Transaction;
import org.hibernate.boot.spi.SessionFactoryOptions;
-import org.hibernate.cache.spi.CacheKey;
import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
@@ -58,7 +57,6 @@
import org.hibernate.resource.transaction.TransactionCoordinatorBuilder.TransactionCoordinatorOptions;
import org.hibernate.resource.transaction.spi.TransactionStatus;
import org.hibernate.service.ServiceRegistry;
-import org.hibernate.type.Type;
/**
* Functionality common to stateless and stateful sessions
@@ -336,11 +334,6 @@ public EntityKey generateEntityKey(Serializable id, EntityPersister persister) {
return new EntityKey( id, persister );
}
- @Override
- public CacheKey generateCacheKey(Serializable id, Type type, String entityOrRoleName) {
- return new CacheKey( id, type, entityOrRoleName, getTenantIdentifier(), getFactory() );
- }
-
private transient JdbcConnectionAccess jdbcConnectionAccess;
@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java
index 94769b542ad9..dfac9b16a3de 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java
@@ -14,11 +14,12 @@
import org.hibernate.HibernateException;
import org.hibernate.boot.spi.SessionFactoryOptions;
-import org.hibernate.cache.spi.CacheKey;
import org.hibernate.cache.spi.QueryCache;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.UpdateTimestampsCache;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.engine.spi.CacheImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
@@ -73,8 +74,14 @@ public boolean containsEntity(Class entityClass, Serializable identifier) {
@Override
public boolean containsEntity(String entityName, Serializable identifier) {
EntityPersister p = sessionFactory.getEntityPersister( entityName );
- return p.hasCache() &&
- p.getCacheAccessStrategy().getRegion().contains( buildCacheKey( identifier, p ) );
+ if ( p.hasCache() ) {
+ EntityRegionAccessStrategy cache = p.getCacheAccessStrategy();
+ Object key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy
+ return cache.getRegion().contains( key );
+ }
+ else {
+ return false;
+ }
}
@Override
@@ -92,20 +99,12 @@ public void evictEntity(String entityName, Serializable identifier) {
MessageHelper.infoString( p, identifier, sessionFactory )
);
}
- p.getCacheAccessStrategy().evict( buildCacheKey( identifier, p ) );
+ EntityRegionAccessStrategy cache = p.getCacheAccessStrategy();
+ Object key = cache.generateCacheKey( identifier, p, sessionFactory, null ); // have to assume non tenancy
+ cache.evict( key );
}
}
- private CacheKey buildCacheKey(Serializable identifier, EntityPersister p) {
- return new CacheKey(
- identifier,
- p.getIdentifierType(),
- p.getRootEntityName(),
- null, // have to assume non tenancy
- sessionFactory
- );
- }
-
@Override
public void evictEntityRegion(Class entityClass) {
evictEntityRegion( entityClass.getName() );
@@ -155,8 +154,14 @@ public void evictNaturalIdRegions() {
@Override
public boolean containsCollection(String role, Serializable ownerIdentifier) {
CollectionPersister p = sessionFactory.getCollectionPersister( role );
- return p.hasCache() &&
- p.getCacheAccessStrategy().getRegion().contains( buildCacheKey( ownerIdentifier, p ) );
+ if ( p.hasCache() ) {
+ CollectionRegionAccessStrategy cache = p.getCacheAccessStrategy();
+ Object key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy
+ return cache.getRegion().contains( key );
+ }
+ else {
+ return false;
+ }
}
@Override
@@ -169,21 +174,12 @@ public void evictCollection(String role, Serializable ownerIdentifier) {
MessageHelper.collectionInfoString( p, ownerIdentifier, sessionFactory )
);
}
- CacheKey cacheKey = buildCacheKey( ownerIdentifier, p );
- p.getCacheAccessStrategy().evict( cacheKey );
+ CollectionRegionAccessStrategy cache = p.getCacheAccessStrategy();
+ Object key = cache.generateCacheKey( ownerIdentifier, p, sessionFactory, null ); // have to assume non tenancy
+ cache.evict( key );
}
}
- private CacheKey buildCacheKey(Serializable ownerIdentifier, CollectionPersister p) {
- return new CacheKey(
- ownerIdentifier,
- p.getKeyType(),
- p.getRole(),
- null, // have to assume non tenancy
- sessionFactory
- );
- }
-
@Override
public void evictCollectionRegion(String role) {
CollectionPersister p = sessionFactory.getCollectionPersister( role );
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java
index 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 404b572d1923..9c2c42507284 100755
--- a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java
@@ -28,7 +28,7 @@
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;
import org.hibernate.UnresolvableObjectException;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.SessionEventListenerManagerImpl;
import org.hibernate.engine.internal.StatefulPersistenceContext;
@@ -270,8 +270,9 @@ public void refresh(String entityName, Object entity, LockMode lockMode) {
// }
if ( persister.hasCache() ) {
- final CacheKey ck = generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() );
- persister.getCacheAccessStrategy().evict( ck );
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey( id, persister, getFactory(), getTenantIdentifier() );
+ cache.evict( ck );
}
String previousFetchProfile = this.getLoadQueryInfluencers().getInternalFetchProfile();
Object result = null;
diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java
index 84c01c97fff1..51bc9b9a2b01 100644
--- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java
+++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java
@@ -35,6 +35,7 @@
import org.hibernate.cache.spi.FilterKey;
import org.hibernate.cache.spi.QueryCache;
import org.hibernate.cache.spi.QueryKey;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.entry.CacheEntry;
import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl;
import org.hibernate.collection.spi.PersistentCollection;
@@ -1620,15 +1621,14 @@ private Object instanceNotYetLoaded(
// see if the entity defines reference caching, and if so use the cached reference (if one).
if ( session.getCacheMode().isGetEnabled() && persister.canUseReferenceCacheEntries() ) {
- final Object cachedEntry = CacheHelper.fromSharedCache(
- session,
- session.generateCacheKey(
- key.getIdentifier(),
- persister.getEntityMetamodel().getEntityType(),
- key.getEntityName()
- ),
- persister.getCacheAccessStrategy()
- );
+ final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey(
+ key.getIdentifier(),
+ persister,
+ session.getFactory(),
+ session.getTenantIdentifier()
+ );
+ final Object cachedEntry = CacheHelper.fromSharedCache( session, ck, cache );
if ( cachedEntry != null ) {
CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( cachedEntry, factory );
return ( (ReferenceCacheEntryImpl) entry ).getReference();
diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
index 964b32e22003..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.CacheKey;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.entry.CacheEntry;
@@ -906,8 +905,9 @@ public Object initializeLazyProperty(String fieldName, Object entity, SessionImp
}
if ( session.getCacheMode().isGetEnabled() && hasCache() ) {
- final CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getRootEntityName() );
- final Object ce = CacheHelper.fromSharedCache( session, cacheKey, getCacheAccessStrategy() );
+ final EntityRegionAccessStrategy cache = getCacheAccessStrategy();
+ final Object cacheKey = cache.generateCacheKey(id, this, session.getFactory(), session.getTenantIdentifier() );
+ final Object ce = CacheHelper.fromSharedCache( session, cacheKey, cache );
if ( ce != null ) {
final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure( ce, factory );
if ( !cacheEntry.areLazyPropertiesUnfetched() ) {
@@ -4269,7 +4269,8 @@ public Boolean isTransient(Object entity, SessionImplementor session) throws Hib
// check to see if it is in the second-level cache
if ( session.getCacheMode().isGetEnabled() && hasCache() ) {
- final CacheKey ck = session.generateCacheKey( id, getIdentifierType(), getRootEntityName() );
+ final EntityRegionAccessStrategy cache = getCacheAccessStrategy();
+ final Object ck = cache.generateCacheKey( id, this, session.getFactory(), session.getTenantIdentifier() );
final Object ce = CacheHelper.fromSharedCache( session, ck, getCacheAccessStrategy() );
if ( ce != null ) {
return Boolean.FALSE;
diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java
index db14beb0c18d..7eedbe4676f5 100644
--- a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java
@@ -13,8 +13,8 @@
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.hibernate.cache.spi.NaturalIdCacheKey;
import org.hibernate.cache.spi.Region;
+import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.stat.NaturalIdCacheStatistics;
/**
@@ -25,6 +25,7 @@
public class ConcurrentNaturalIdCacheStatisticsImpl extends CategorizedStatistics implements NaturalIdCacheStatistics {
private static final long serialVersionUID = 1L;
private final transient Region region;
+ private final transient NaturalIdRegionAccessStrategy accessStrategy;
private final AtomicLong hitCount = new AtomicLong();
private final AtomicLong missCount = new AtomicLong();
private final AtomicLong putCount = new AtomicLong();
@@ -35,15 +36,17 @@ public class ConcurrentNaturalIdCacheStatisticsImpl extends CategorizedStatistic
private final Lock readLock;
private final Lock writeLock;
+
{
final ReadWriteLock lock = new ReentrantReadWriteLock();
this.readLock = lock.readLock();
this.writeLock = lock.writeLock();
}
- ConcurrentNaturalIdCacheStatisticsImpl(Region region) {
+ ConcurrentNaturalIdCacheStatisticsImpl(Region region, NaturalIdRegionAccessStrategy accessStrategy) {
super( region.getName() );
this.region = region;
+ this.accessStrategy = accessStrategy;
}
@Override
@@ -126,8 +129,8 @@ public long getSizeInMemory() {
public Map getEntries() {
final Map map = new HashMap();
for ( Object o : this.region.toMap().entrySet() ) {
- final Map.Entry me = (Map.Entry) o;
- map.put( ( (NaturalIdCacheKey) me.getKey() ).getNaturalIdValues(), me.getValue() );
+ Map.Entry me = (Map.Entry) o;
+ map.put( accessStrategy.getNaturalIdValues(me.getKey()), me.getValue() );
}
return map;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentSecondLevelCacheStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentSecondLevelCacheStatisticsImpl.java
index d7292d231f2a..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.CacheKey;
import org.hibernate.cache.spi.Region;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.stat.SecondLevelCacheStatistics;
/**
@@ -22,13 +22,19 @@
*/
public class ConcurrentSecondLevelCacheStatisticsImpl extends CategorizedStatistics implements SecondLevelCacheStatistics {
private final transient Region region;
+ private final transient EntityRegionAccessStrategy entityRegionAccessStrategy;
+ private final transient CollectionRegionAccessStrategy collectionRegionAccessStrategy;
private AtomicLong hitCount = new AtomicLong();
private AtomicLong missCount = new AtomicLong();
private AtomicLong putCount = new AtomicLong();
- ConcurrentSecondLevelCacheStatisticsImpl(Region region) {
+ ConcurrentSecondLevelCacheStatisticsImpl(Region region,
+ EntityRegionAccessStrategy entityRegionAccessStrategy,
+ CollectionRegionAccessStrategy collectionRegionAccessStrategy) {
super( region.getName() );
this.region = region;
+ this.entityRegionAccessStrategy = entityRegionAccessStrategy;
+ this.collectionRegionAccessStrategy = collectionRegionAccessStrategy;
}
public long getHitCount() {
@@ -57,10 +63,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(((CacheKey) me.getKey()).getKey(), me.getValue());
+ for (Object o : region.toMap().entrySet()) {
+ Map.Entry me = (Map.Entry) o;
+ Object id;
+ if (entityRegionAccessStrategy != null) {
+ id = entityRegionAccessStrategy.getCacheKeyId(me.getKey());
+ } else if (collectionRegionAccessStrategy != null) {
+ id = collectionRegionAccessStrategy.getCacheKeyId(me.getKey());
+ } else {
+ id = me.getKey();
+ }
+ map.put(id, me.getValue());
}
return map;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java
index b9b6e87deefd..16b5478fb6f5 100644
--- a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java
@@ -11,6 +11,10 @@
import java.util.concurrent.atomic.AtomicLong;
import org.hibernate.cache.spi.Region;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
+import org.hibernate.cache.spi.access.RegionAccessStrategy;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.ArrayHelper;
@@ -299,7 +303,10 @@ public NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName) {
if ( region == null ) {
return null;
}
- nics = new ConcurrentNaturalIdCacheStatisticsImpl( region );
+ NaturalIdRegionAccessStrategy accessStrategy
+ = (NaturalIdRegionAccessStrategy) sessionFactory.getNaturalIdCacheRegionAccessStrategy(regionName);
+
+ nics = new ConcurrentNaturalIdCacheStatisticsImpl( region, accessStrategy );
ConcurrentNaturalIdCacheStatisticsImpl previous;
if ( ( previous = (ConcurrentNaturalIdCacheStatisticsImpl) naturalIdCacheStatistics.putIfAbsent(
regionName, nics
@@ -328,7 +335,16 @@ public SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionNam
if ( region == null ) {
return null;
}
- slcs = new ConcurrentSecondLevelCacheStatisticsImpl( region );
+ RegionAccessStrategy accessStrategy = sessionFactory.getSecondLevelCacheRegionAccessStrategy(regionName);
+
+ EntityRegionAccessStrategy entityRegionAccessStrategy
+ = accessStrategy instanceof EntityRegionAccessStrategy ?
+ (EntityRegionAccessStrategy) accessStrategy : null;
+ CollectionRegionAccessStrategy collectionRegionAccessStrategy
+ = accessStrategy instanceof CollectionRegionAccessStrategy ?
+ (CollectionRegionAccessStrategy) accessStrategy : null;
+
+ slcs = new ConcurrentSecondLevelCacheStatisticsImpl( region, entityRegionAccessStrategy, collectionRegionAccessStrategy );
ConcurrentSecondLevelCacheStatisticsImpl previous;
if ( ( previous = (ConcurrentSecondLevelCacheStatisticsImpl) secondLevelCacheStatistics.putIfAbsent(
regionName, slcs
diff --git a/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java b/hibernate-core/src/test/java/org/hibernate/cache/spi/NaturalIdCacheKeyTest.java
index cd9e92612561..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
@@ -6,18 +6,13 @@
*/
package org.hibernate.cache.spi;
-import static junit.framework.Assert.assertEquals;
-import static org.junit.Assert.assertArrayEquals;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
+import org.hibernate.cache.internal.OldNaturalIdCacheKey;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
@@ -26,6 +21,13 @@
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
public class NaturalIdCacheKeyTest {
@Test
public void testSerializationRoundTrip() throws Exception {
@@ -58,15 +60,15 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
return invocation.getArguments()[0];
}
});
-
- final NaturalIdCacheKey key = new NaturalIdCacheKey(new Object[] {"a", "b", "c"}, entityPersister, sessionImplementor);
-
+
+ final OldNaturalIdCacheKey key = (OldNaturalIdCacheKey) DefaultCacheKeysFactory.createNaturalIdKey( new Object[] {"a", "b", "c"}, entityPersister, sessionImplementor );
+
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(key);
final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
- final NaturalIdCacheKey keyClone = (NaturalIdCacheKey)ois.readObject();
+ final OldNaturalIdCacheKey keyClone = (OldNaturalIdCacheKey) ois.readObject();
assertEquals(key, keyClone);
assertEquals(key.hashCode(), keyClone.hashCode());
diff --git a/hibernate-core/src/test/java/org/hibernate/test/filter/DynamicFilterTest.java b/hibernate-core/src/test/java/org/hibernate/test/filter/DynamicFilterTest.java
index 8a3ae668bc4e..2357c7071627 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/filter/DynamicFilterTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/filter/DynamicFilterTest.java
@@ -20,7 +20,7 @@
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
-import org.hibernate.cache.spi.CacheKey;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.entry.CollectionCacheEntry;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.criterion.DetachedCriteria;
@@ -100,12 +100,14 @@ public void testSecondLevelCachedCollectionsFiltering() {
Hibernate.initialize( sp.getOrders() );
CollectionPersister persister = sessionFactory().getCollectionPersister( Salesperson.class.getName() + ".orders" );
assertTrue( "No cache for collection", persister.hasCache() );
- CacheKey cacheKey = ( (SessionImplementor) session ).generateCacheKey(
+ CollectionRegionAccessStrategy cache = persister.getCacheAccessStrategy();
+ Object cacheKey = cache.generateCacheKey(
testData.steveId,
- persister.getKeyType(),
- persister.getRole()
+ persister,
+ sessionFactory(),
+ session.getTenantIdentifier()
);
- CollectionCacheEntry cachedData = ( CollectionCacheEntry ) persister.getCacheAccessStrategy().get( cacheKey, ts );
+ CollectionCacheEntry cachedData = ( CollectionCacheEntry ) cache.get( cacheKey, ts );
assertNotNull( "collection was not in cache", cachedData );
session.close();
@@ -114,14 +116,15 @@ public void testSecondLevelCachedCollectionsFiltering() {
ts = ( ( SessionImplementor ) session ).getTimestamp();
session.enableFilter( "fulfilledOrders" ).setParameter( "asOfDate", testData.lastMonth.getTime() );
sp = ( Salesperson ) session.createQuery( "from Salesperson as s where s.id = :id" )
- .setLong( "id", testData.steveId )
- .uniqueResult();
+ .setLong( "id", testData.steveId )
+ .uniqueResult();
assertEquals( "Filtered-collection not bypassing 2L-cache", 1, sp.getOrders().size() );
- CacheKey cacheKey2 = ( (SessionImplementor) session ).generateCacheKey(
+ Object cacheKey2 = cache.generateCacheKey(
testData.steveId,
- persister.getKeyType(),
- persister.getRole()
+ persister,
+ sessionFactory(),
+ session.getTenantIdentifier()
);
CollectionCacheEntry cachedData2 = ( CollectionCacheEntry ) persister.getCacheAccessStrategy().get( cacheKey2, ts );
assertNotNull( "collection no longer in cache!", cachedData2 );
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareCollectionRegionAccessStrategy.java
index e22c9b5d1ebb..ffa8c52fef85 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareCollectionRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareCollectionRegionAccessStrategy.java
@@ -7,11 +7,13 @@
package org.hibernate.cache.ehcache.internal.nonstop;
import net.sf.ehcache.constructs.nonstop.NonStopCacheException;
-
import org.hibernate.cache.CacheException;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
/**
* Implementation of {@link CollectionRegionAccessStrategy} that handles {@link NonStopCacheException} using
@@ -158,4 +160,13 @@ public void unlockRegion(SoftLock lock) throws CacheException {
}
}
+ @Override
+ public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier );
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getCollectionId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareEntityRegionAccessStrategy.java
index b54154faba84..7371faaf8998 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareEntityRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareEntityRegionAccessStrategy.java
@@ -7,11 +7,13 @@
package org.hibernate.cache.ehcache.internal.nonstop;
import net.sf.ehcache.constructs.nonstop.NonStopCacheException;
-
import org.hibernate.cache.CacheException;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Implementation of {@link EntityRegionAccessStrategy} that handles {@link net.sf.ehcache.constructs.nonstop.NonStopCacheException} using
@@ -203,4 +205,14 @@ public boolean update(Object key, Object value, Object currentVersion, Object pr
return false;
}
}
+
+ @Override
+ public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier );
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getEntityId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareNaturalIdRegionAccessStrategy.java
index f259b2370ab2..67d3283830b6 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareNaturalIdRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/nonstop/NonstopAwareNaturalIdRegionAccessStrategy.java
@@ -7,11 +7,13 @@
package org.hibernate.cache.ehcache.internal.nonstop;
import net.sf.ehcache.constructs.nonstop.NonStopCacheException;
-
import org.hibernate.cache.CacheException;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Implementation of {@link NaturalIdRegionAccessStrategy} that handles {@link NonStopCacheException} using
@@ -202,4 +204,13 @@ public void unlockRegion(SoftLock lock) throws CacheException {
}
}
+ @Override
+ public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
+ return DefaultCacheKeysFactory.createNaturalIdKey( naturalIdValues, persister, session );
+ }
+
+ @Override
+ public Object[] getNaturalIdValues(Object cacheKey) {
+ return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractReadWriteEhcacheAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractReadWriteEhcacheAccessStrategy.java
index a17c67e13e05..192647e3efe2 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractReadWriteEhcacheAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/AbstractReadWriteEhcacheAccessStrategy.java
@@ -16,7 +16,6 @@
import org.hibernate.cache.ehcache.EhCacheMessageLogger;
import org.hibernate.cache.ehcache.internal.regions.EhcacheTransactionalDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
-
import org.jboss.logging.Logger;
/**
@@ -27,8 +26,7 @@
* @author Chris Dennis
* @author Alex Snaps
*/
-abstract class AbstractReadWriteEhcacheAccessStrategy
+abstract class AbstractReadWriteEhcacheAccessStrategy
extends AbstractEhcacheAccessStrategy {
private static final EhCacheMessageLogger LOG = Logger.getMessageLogger(
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheCollectionRegionAccessStrategy.java
index 3d8170fb2712..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,9 +9,12 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
/**
* Ehcache specific non-strict read/write collection region access strategy
@@ -79,4 +82,14 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException {
public void remove(Object key) throws CacheException {
region().remove( key );
}
+
+ @Override
+ public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier );
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getCollectionId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheEntityRegionAccessStrategy.java
index abe9ee21b680..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
@@ -9,9 +9,12 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Ehcache specific non-strict read/write entity region access strategy
@@ -118,4 +121,14 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje
public void remove(Object key) throws CacheException {
region().remove( key );
}
+
+ @Override
+ public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier );
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getEntityId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/NonStrictReadWriteEhcacheNaturalIdRegionAccessStrategy.java
index a25baea452bb..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,9 +9,12 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Ehcache specific non-strict read/write NaturalId region access strategy
@@ -116,4 +119,14 @@ public boolean afterUpdate(Object key, Object value, SoftLock lock) throws Cache
public void remove(Object key) throws CacheException {
region().remove( key );
}
+
+ @Override
+ public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
+ return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session);
+ }
+
+ @Override
+ public Object[] getNaturalIdValues(Object cacheKey) {
+ return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheCollectionRegionAccessStrategy.java
index 08b1870758a1..7de3b272eddc 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheCollectionRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheCollectionRegionAccessStrategy.java
@@ -9,9 +9,12 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
/**
* Ehcache specific read-only collection region access strategy
@@ -68,4 +71,14 @@ public SoftLock lockItem(Object key, Object version) throws UnsupportedOperation
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
}
+
+ @Override
+ public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier );
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getCollectionId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheEntityRegionAccessStrategy.java
index c7d0fd050644..43d16d3f7071 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheEntityRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheEntityRegionAccessStrategy.java
@@ -9,9 +9,12 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Ehcache specific read-only entity region access strategy
@@ -110,4 +113,14 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje
throws UnsupportedOperationException {
throw new UnsupportedOperationException( "Can't write to a readonly object" );
}
+
+ @Override
+ public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createEntityKey( id, persister, factory, tenantIdentifier );
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getEntityId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheNaturalIdRegionAccessStrategy.java
index fd51e20ca433..35926666b9e9 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheNaturalIdRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadOnlyEhcacheNaturalIdRegionAccessStrategy.java
@@ -9,9 +9,12 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Ehcache specific read-only NaturalId region access strategy
@@ -109,4 +112,14 @@ public boolean update(Object key, Object value) throws UnsupportedOperationExcep
public boolean afterUpdate(Object key, Object value, SoftLock lock) throws UnsupportedOperationException {
throw new UnsupportedOperationException( "Can't write to a readonly object" );
}
+
+ @Override
+ public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
+ return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session);
+ }
+
+ @Override
+ public Object[] getNaturalIdValues(Object cacheKey) {
+ return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheCollectionRegionAccessStrategy.java
index 02dd3106ed11..2402e372f325 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheCollectionRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheCollectionRegionAccessStrategy.java
@@ -8,8 +8,11 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
/**
* Ehcache specific read/write collection region access strategy
@@ -35,4 +38,15 @@ public ReadWriteEhcacheCollectionRegionAccessStrategy(EhcacheCollectionRegion re
public CollectionRegion getRegion() {
return region();
}
+
+
+ @Override
+ public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier );
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getCollectionId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheEntityRegionAccessStrategy.java
index d887bab7d4c2..a691e2bc9a06 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheEntityRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheEntityRegionAccessStrategy.java
@@ -9,9 +9,12 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Ehcache specific read/write entity region access strategy
@@ -117,4 +120,14 @@ public boolean afterUpdate(Object key, Object value, Object currentVersion, Obje
region().writeUnlock( key );
}
}
+
+ @Override
+ public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier);
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getEntityId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheNaturalIdRegionAccessStrategy.java
index d40da2186e28..61fcb06a7dc8 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheNaturalIdRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/ReadWriteEhcacheNaturalIdRegionAccessStrategy.java
@@ -9,9 +9,12 @@
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* Ehcache specific read/write NaturalId region access strategy
@@ -115,4 +118,14 @@ public boolean afterUpdate(Object key, Object value, SoftLock lock) throws Cache
region().writeUnlock( key );
}
}
+
+ @Override
+ public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
+ return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session);
+ }
+
+ @Override
+ public Object[] getNaturalIdValues(Object cacheKey) {
+ return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheCollectionRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheCollectionRegionAccessStrategy.java
index dddec56ef49d..c23efe9a9419 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheCollectionRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheCollectionRegionAccessStrategy.java
@@ -8,13 +8,15 @@
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
-
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheCollectionRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
/**
* JTA CollectionRegionAccessStrategy.
@@ -100,4 +102,13 @@ public void unlockItem(Object key, SoftLock lock) throws CacheException {
// no-op
}
+ @Override
+ public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createCollectionKey( id, persister, factory, tenantIdentifier );
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getCollectionId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheEntityRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheEntityRegionAccessStrategy.java
index 82f3072cdf32..1cc4a2e504ac 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheEntityRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheEntityRegionAccessStrategy.java
@@ -8,13 +8,15 @@
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
-
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheEntityRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* JTA EntityRegionAccessStrategy.
@@ -136,4 +138,14 @@ public boolean update(
throw new CacheException( e );
}
}
+
+ @Override
+ public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
+ return DefaultCacheKeysFactory.createEntityKey(id, persister, factory, tenantIdentifier);
+ }
+
+ @Override
+ public Object getCacheKeyId(Object cacheKey) {
+ return DefaultCacheKeysFactory.getEntityId(cacheKey);
+ }
}
diff --git a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheNaturalIdRegionAccessStrategy.java b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheNaturalIdRegionAccessStrategy.java
index 1d5fa9a195e9..a840c2325034 100644
--- a/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheNaturalIdRegionAccessStrategy.java
+++ b/hibernate-ehcache/src/main/java/org/hibernate/cache/ehcache/internal/strategy/TransactionalEhcacheNaturalIdRegionAccessStrategy.java
@@ -8,13 +8,15 @@
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
-
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.ehcache.internal.regions.EhcacheNaturalIdRegion;
+import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
/**
* JTA NaturalIdRegionAccessStrategy.
@@ -133,4 +135,13 @@ public boolean update(Object key, Object value) throws CacheException {
}
}
+ @Override
+ public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
+ return DefaultCacheKeysFactory.createNaturalIdKey(naturalIdValues, persister, session);
+ }
+
+ @Override
+ public Object[] getNaturalIdValues(Object cacheKey) {
+ return DefaultCacheKeysFactory.getNaturalIdValues(cacheKey);
+ }
}
diff --git a/hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/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
*
@@ -52,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
@@ -88,26 +93,15 @@ public class PutFromLoadValidator {
*/
private final ConcurrentMap