HHH-16172 Expose internal state of 2nd-level cache keys

This commit is contained in:
Paul Ferraro 2023-02-11 22:01:13 -05:00 committed by Sanne Grinovero
parent 4e961e85c8
commit 105253df5f
3 changed files with 65 additions and 17 deletions

View File

@ -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 ) {

View File

@ -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 ) {

View File

@ -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();
}