Skip to content

Commit

Permalink
HHH-15500 Cache key is huge since migration to 6
Browse files Browse the repository at this point in the history
  • Loading branch information
dreab8 authored and beikov committed Sep 21, 2022
1 parent 89a98f2 commit 893e1b0
Show file tree
Hide file tree
Showing 52 changed files with 565 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,19 @@ public CacheKeyImplementation(
final String tenantId,
final SessionFactoryImplementor factory) {
this.id = id;
this.cacheKeyValueDescriptor = type.toCacheKeyDescriptor( factory );
this.entityOrRoleName = entityOrRoleName;
this.tenantId = tenantId;
this.hashCode = calculateHashCode( );
final CacheKeyValueDescriptor cacheKeyValueDescriptor = type.toCacheKeyDescriptor( factory );
// Optimization for the very common case Integer/Long etc. which use the default cache key descriptor
// Doing this helps to avoid megamorphic call sites and reduces the cache key serialization size
if ( cacheKeyValueDescriptor == DefaultCacheKeyValueDescriptor.INSTANCE ) {
this.cacheKeyValueDescriptor = null;
this.hashCode = Objects.hashCode( id );
}
else {
this.cacheKeyValueDescriptor = cacheKeyValueDescriptor;
this.hashCode = calculateHashCode();
}
}

private int calculateHashCode() {
Expand All @@ -74,14 +83,23 @@ public boolean equals(Object other) {
if ( this == other ) {
return true;
}
if ( hashCode != other.hashCode() || !( other instanceof CacheKeyImplementation) ) {
if ( hashCode != other.hashCode() || !( other instanceof CacheKeyImplementation ) ) {
//hashCode is part of this check since it is pre-calculated and hash must match for equals to be true
return false;
}
final CacheKeyImplementation that = (CacheKeyImplementation) other;
return Objects.equals( entityOrRoleName, that.entityOrRoleName )
&& cacheKeyValueDescriptor.isEqual( id, that.id )
&& Objects.equals( tenantId, that.tenantId );
if ( !entityOrRoleName.equals( that.entityOrRoleName ) ) {
return false;
}
if ( cacheKeyValueDescriptor == null ) {
if ( !Objects.equals( id, that.id ) ) {
return false;
}
}
else if ( !cacheKeyValueDescriptor.isEqual( id, that.id ) ) {
return false;
}
return Objects.equals( tenantId, that.tenantId );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@
* @see CustomComponentCacheKeyValueDescriptor
*/
public class ComponentCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
private final NavigableRole role;
private final String role;
private final SessionFactoryImplementor sessionFactory;

private transient EmbeddableValuedModelPart embeddedMapping;

public ComponentCacheKeyValueDescriptor(NavigableRole role, SessionFactoryImplementor sessionFactory) {
this.role = role;
public ComponentCacheKeyValueDescriptor(
EmbeddableValuedModelPart embeddedMapping,
SessionFactoryImplementor sessionFactory) {
this.role = embeddedMapping.getNavigableRole().getFullPath();
this.sessionFactory = sessionFactory;
this.embeddedMapping = embeddedMapping;
}

@Override
Expand Down Expand Up @@ -82,10 +85,12 @@ public Object getAttributeValue(Object component, int i, AttributeMapping attr)
}
}


private EmbeddableValuedModelPart getEmbeddedMapping() {
EmbeddableValuedModelPart embeddedMapping = this.embeddedMapping;
if ( embeddedMapping == null ) {
embeddedMapping = sessionFactory.getRuntimeMetamodels().getEmbedded( role );
this.embeddedMapping = embeddedMapping = sessionFactory.getRuntimeMetamodels().getEmbedded(
new NavigableRole( role )
);
}
return embeddedMapping;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,15 @@
*/
package org.hibernate.cache.internal;

import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.usertype.CompositeUserType;

/**
* CacheKeyValueDescriptor used to describe CompositeUserType mappings
*/
public class CustomComponentCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
private final NavigableRole role;
private final CompositeUserType<Object> compositeUserType;

public CustomComponentCacheKeyValueDescriptor(
NavigableRole role,
CompositeUserType<Object> compositeUserType) {
this.role = role;
public CustomComponentCacheKeyValueDescriptor(CompositeUserType<Object> compositeUserType) {
this.compositeUserType = compositeUserType;
}

Expand All @@ -33,8 +28,4 @@ public boolean isEqual(Object key1, Object key2) {
return compositeUserType.equals( key1, key2 );
}

@Override
public String toString() {
return "CustomComponentCacheKeyValueDescriptor(" + role + ")";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.cache.internal;

import java.util.Objects;

public class DefaultCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
public static final DefaultCacheKeyValueDescriptor INSTANCE = new DefaultCacheKeyValueDescriptor();

@Override
public int getHashCode(Object key) {
return key.hashCode();
}

@Override
public boolean isEqual(Object key1, Object key2) {
return Objects.equals( key1, key2 );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.cache.internal;

import org.hibernate.type.descriptor.java.JavaType;

public class JavaTypeCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
private final JavaType<Object> javaType;

public JavaTypeCacheKeyValueDescriptor(JavaType<?> javaType) {
//noinspection unchecked
this.javaType = (JavaType<Object>) javaType;
}

@Override
public int getHashCode(Object key) {
return javaType.extractHashCode( key );
}

@Override
public boolean isEqual(Object key1, Object key2) {
return javaType.areEqual( key1, key2 );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,12 @@
* Base support for EmbeddableMappingType implementations
*/
public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType {
protected final SessionFactoryImplementor sessionFactory;

public AbstractEmbeddableMapping(MappingModelCreationProcess creationProcess) {
this( creationProcess.getCreationContext() );
}

public AbstractEmbeddableMapping(RuntimeModelCreationContext creationContext) {
this( creationContext.getSessionFactory() );
}

protected AbstractEmbeddableMapping(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private EmbeddableMappingTypeImpl(
this.embeddableJtd = representationStrategy.getMappedJavaType();
this.valueMapping = embeddedPartBuilder.apply( this );

final ConfigurationService cs = sessionFactory.getServiceRegistry()
final ConfigurationService cs = creationContext.getSessionFactory().getServiceRegistry()
.getService(ConfigurationService.class);

this.createEmptyCompositesEnabled = ConfigurationHelper.getBoolean(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public IdClassEmbeddable(
this.idMapping = idMapping;
this.virtualIdEmbeddable = virtualIdEmbeddable;

this.javaType = sessionFactory.getTypeConfiguration()
this.javaType = creationProcess.getCreationContext().getSessionFactory().getTypeConfiguration()
.getJavaTypeRegistry()
.resolveManagedTypeDescriptor( idClassSource.getComponentClass() );

Expand Down Expand Up @@ -176,7 +176,7 @@ public EmbeddableValuedModelPart getEmbeddedPart() {
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
final Object id = representationStrategy.getInstantiator().instantiate(
null,
sessionFactory
session.getSessionFactory()
);

final List<AttributeMapping> virtualIdAttribute = virtualIdEmbeddable.getAttributeMappings();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
private final CompositeUserType<Object> compositeUserType;

private EmbeddableValuedModelPart mappingModelPart;
private CacheKeyValueDescriptor cacheKeyValueDescriptor;
private transient CacheKeyValueDescriptor cacheKeyValueDescriptor;

public ComponentType(Component component, int[] originalPropertyOrder, MetadataBuildingContext buildingContext) {
this.componentClass = component.isDynamic()
Expand Down Expand Up @@ -705,19 +705,15 @@ public boolean[] toColumnNullness(Object value, Mapping mapping) {

@Override
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
CacheKeyValueDescriptor cacheKeyValueDescriptor = this.cacheKeyValueDescriptor;
if ( cacheKeyValueDescriptor == null ) {
if ( compositeUserType != null ) {
cacheKeyValueDescriptor = new CustomComponentCacheKeyValueDescriptor(
mappingModelPart.getNavigableRole(),
compositeUserType
);
cacheKeyValueDescriptor = new CustomComponentCacheKeyValueDescriptor( compositeUserType );
}
else {
cacheKeyValueDescriptor = new ComponentCacheKeyValueDescriptor(
mappingModelPart.getNavigableRole(),
sessionFactory
);
cacheKeyValueDescriptor = new ComponentCacheKeyValueDescriptor( mappingModelPart, sessionFactory );
}
this.cacheKeyValueDescriptor = cacheKeyValueDescriptor;
}

return cacheKeyValueDescriptor;
Expand Down
31 changes: 31 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/type/CustomType.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.cache.internal.CacheKeyValueDescriptor;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
Expand Down Expand Up @@ -66,6 +67,8 @@ public class CustomType<J>
private final ValueBinder<J> valueBinder;
private final JdbcLiteralFormatter<J> jdbcLiteralFormatter;

private transient CacheKeyValueDescriptor cacheKeyValueDescriptor;

public CustomType(UserType<J> userType, TypeConfiguration typeConfiguration) throws MappingException {
this( userType, ArrayHelper.EMPTY_STRING_ARRAY, typeConfiguration );
}
Expand Down Expand Up @@ -388,4 +391,32 @@ public JavaType<?> getJdbcJavaType() {
public BasicValueConverter<J, Object> getValueConverter() {
return userType.getValueConverter();
}

@Override
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
CacheKeyValueDescriptor cacheKeyValueDescriptor = this.cacheKeyValueDescriptor;
if ( cacheKeyValueDescriptor == null ) {
this.cacheKeyValueDescriptor = cacheKeyValueDescriptor = new CustomTypeCacheKeyValueDescriptor( getUserType() );
}
return cacheKeyValueDescriptor;
}

private static final class CustomTypeCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
private final UserType<Object> userType;

public CustomTypeCacheKeyValueDescriptor(UserType<?> userType) {
//noinspection unchecked
this.userType = (UserType<Object>) userType;
}

@Override
public int getHashCode(Object key) {
return userType.hashCode( key );
}

@Override
public boolean isEqual(Object key1, Object key2) {
return userType.equals( key1, key2 );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import java.math.BigInteger;
import java.util.Locale;

import org.hibernate.cache.internal.CacheKeyValueDescriptor;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcType;

Expand Down Expand Up @@ -44,6 +46,11 @@ public int extractHashCode(BigDecimal value) {
return value.intValue();
}

@Override
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
return BigNumberCacheKeyValueDescriptor.INSTANCE;
}

@SuppressWarnings("unchecked")
public <X> X unwrap(BigDecimal value, Class<X> type, WrapperOptions options) {
if ( value == null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import java.math.BigInteger;
import java.util.Locale;

import org.hibernate.cache.internal.CacheKeyValueDescriptor;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcType;

Expand Down Expand Up @@ -46,6 +48,11 @@ public boolean areEqual(BigInteger one, BigInteger another) {
return one == another || ( one != null && another != null && one.compareTo( another ) == 0 );
}

@Override
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
return BigNumberCacheKeyValueDescriptor.INSTANCE;
}

@Override
@SuppressWarnings("unchecked")
public <X> X unwrap(BigInteger value, Class<X> type, WrapperOptions options) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.type.descriptor.java;

import org.hibernate.cache.internal.CacheKeyValueDescriptor;

final class BigNumberCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
static final BigNumberCacheKeyValueDescriptor INSTANCE = new BigNumberCacheKeyValueDescriptor();

@Override
public int getHashCode(Object key) {
return ( (Number) key ).intValue();
}

@Override
public boolean isEqual(Object key1, Object key2) {
//noinspection unchecked
return ( key1 == key2 ) || ( key1 != null && key2 != null && ( (Comparable<Object>) key1 ).compareTo( key2 ) == 0 );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
*/
package org.hibernate.type.descriptor.java;

import org.hibernate.cache.internal.CacheKeyValueDescriptor;
import org.hibernate.cache.internal.DefaultCacheKeyValueDescriptor;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.spi.PrimitiveJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
Expand Down Expand Up @@ -177,4 +180,9 @@ public String getCheckCondition(String columnName, JdbcType sqlTypeDescriptor, D
);
}

@Override
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
return DefaultCacheKeyValueDescriptor.INSTANCE;
}

}

0 comments on commit 893e1b0

Please sign in to comment.