diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/BasicCacheKeyImplementation.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/BasicCacheKeyImplementation.java index e241ba34c6..7655ac1e0c 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/BasicCacheKeyImplementation.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/BasicCacheKeyImplementation.java @@ -7,10 +7,8 @@ package org.hibernate.cache.internal; import java.io.Serializable; -import java.util.Objects; import org.hibernate.Internal; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -44,11 +42,26 @@ final class BasicCacheKeyImplementation implements Serializable { final Serializable disassembledKey, final Type type, final String entityOrRoleName) { - assert disassembledKey != null; + this( disassembledKey, entityOrRoleName, calculateHashCode( originalId, type ) ); + } + + /** + * Being an internal contract the arguments are not being checked. + * @param originalId + * @param disassembledKey this must be the "disassembled" form of an ID + * @param type + * @param entityOrRoleName + */ + @Internal + public BasicCacheKeyImplementation( + final Serializable id, + final String entityOrRoleName, + final int hashCode) { + assert id != null; assert entityOrRoleName != null; - this.id = disassembledKey; + this.id = id; this.entityOrRoleName = entityOrRoleName; - this.hashCode = calculateHashCode( originalId, type ); + this.hashCode = hashCode; } private static int calculateHashCode(Object disassembledKey, Type type) { @@ -59,6 +72,11 @@ final class BasicCacheKeyImplementation implements Serializable { return id; } + @Internal + public String getEntityOrRoleName() { + return entityOrRoleName; + } + @Override public boolean equals(final Object other) { if ( other == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java index 2822837c6d..1c0569d37c 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java @@ -10,7 +10,6 @@ import java.io.Serializable; import java.util.Objects; import org.hibernate.Internal; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -31,7 +30,7 @@ public final class CacheKeyImplementation implements Serializable { private final String tenantId; private final int hashCode; - //because of object alignmnet, we had "free space" in this key: + //because of object alignment, we had "free space" in this key: //this field isn't strictly necessary but convenient: watch for //class layout changes. private final boolean requiresDeepEquals; @@ -54,12 +53,31 @@ public final class CacheKeyImplementation implements Serializable { final Type type, final String entityOrRoleName, final String tenantId) { + this( disassembledKey, entityOrRoleName, tenantId, calculateHashCode( id, type, tenantId ) ); + } + + /** + * Construct a new key for a collection or entity instance. + * Note that an entity name should always be the root entity + * name, not a subclass entity name. + * + * @param id The identifier associated with the cached data + * @param entityOrRoleName The entity or collection-role name. + * @param tenantId The tenant identifier associated with this data. + * @param hashCode the pre-calculated hash code + */ + @Internal + public CacheKeyImplementation( + final Object id, + final String entityOrRoleName, + final String tenantId, + final int hashCode) { assert entityOrRoleName != null; - this.id = disassembledKey; + this.id = id; this.entityOrRoleName = entityOrRoleName; this.tenantId = tenantId; //might actually be null - this.hashCode = calculateHashCode( id, type, tenantId ); - this.requiresDeepEquals = disassembledKey.getClass().isArray(); + this.hashCode = hashCode; + this.requiresDeepEquals = id.getClass().isArray(); } private static int calculateHashCode(Object id, Type type, String tenantId) { @@ -72,6 +90,16 @@ public final class CacheKeyImplementation implements Serializable { return id; } + @Internal + public String getEntityOrRoleName() { + return entityOrRoleName; + } + + @Internal + public String getTenantId() { + return tenantId; + } + @Override public boolean equals(Object other) { if ( other == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java b/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java index a8e09604a7..89abfd5838 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/internal/NaturalIdCacheKey.java @@ -11,9 +11,9 @@ import java.io.ObjectInputStream; import java.io.Serializable; import java.util.Objects; +import org.hibernate.Internal; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.util.ValueHolder; -import org.hibernate.metamodel.mapping.NaturalIdMapping; import org.hibernate.persister.entity.EntityPersister; /** @@ -38,13 +38,15 @@ public class NaturalIdCacheKey implements Serializable { } public NaturalIdCacheKey(Object naturalIdValues, EntityPersister persister, String entityName, SharedSessionContractImplementor session) { + this( persister.getNaturalIdMapping().disassemble( naturalIdValues, session ), entityName, session.getTenantIdentifier(), persister.getNaturalIdMapping().calculateHashCode( naturalIdValues ) ); + } + + @Internal + public NaturalIdCacheKey(Object naturalIdValues, String entityName, String tenantId, int hashCode) { + this.naturalIdValues = naturalIdValues; this.entityName = entityName; - this.tenantId = session.getTenantIdentifier(); - - final NaturalIdMapping naturalIdMapping = persister.getNaturalIdMapping(); - - this.naturalIdValues = naturalIdMapping.disassemble( naturalIdValues, session ); - this.hashCode = naturalIdMapping.calculateHashCode( naturalIdValues ); + this.tenantId = tenantId; + this.hashCode = hashCode; initTransients(); }