Skip to content

Commit 893e1b0

Browse files
dreab8beikov
authored andcommitted
HHH-15500 Cache key is huge since migration to 6
1 parent 89a98f2 commit 893e1b0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+565
-40
lines changed

hibernate-core/src/main/java/org/hibernate/cache/internal/CacheKeyImplementation.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,19 @@ public CacheKeyImplementation(
5050
final String tenantId,
5151
final SessionFactoryImplementor factory) {
5252
this.id = id;
53-
this.cacheKeyValueDescriptor = type.toCacheKeyDescriptor( factory );
5453
this.entityOrRoleName = entityOrRoleName;
5554
this.tenantId = tenantId;
56-
this.hashCode = calculateHashCode( );
55+
final CacheKeyValueDescriptor cacheKeyValueDescriptor = type.toCacheKeyDescriptor( factory );
56+
// Optimization for the very common case Integer/Long etc. which use the default cache key descriptor
57+
// Doing this helps to avoid megamorphic call sites and reduces the cache key serialization size
58+
if ( cacheKeyValueDescriptor == DefaultCacheKeyValueDescriptor.INSTANCE ) {
59+
this.cacheKeyValueDescriptor = null;
60+
this.hashCode = Objects.hashCode( id );
61+
}
62+
else {
63+
this.cacheKeyValueDescriptor = cacheKeyValueDescriptor;
64+
this.hashCode = calculateHashCode();
65+
}
5766
}
5867

5968
private int calculateHashCode() {
@@ -74,14 +83,23 @@ public boolean equals(Object other) {
7483
if ( this == other ) {
7584
return true;
7685
}
77-
if ( hashCode != other.hashCode() || !( other instanceof CacheKeyImplementation) ) {
86+
if ( hashCode != other.hashCode() || !( other instanceof CacheKeyImplementation ) ) {
7887
//hashCode is part of this check since it is pre-calculated and hash must match for equals to be true
7988
return false;
8089
}
8190
final CacheKeyImplementation that = (CacheKeyImplementation) other;
82-
return Objects.equals( entityOrRoleName, that.entityOrRoleName )
83-
&& cacheKeyValueDescriptor.isEqual( id, that.id )
84-
&& Objects.equals( tenantId, that.tenantId );
91+
if ( !entityOrRoleName.equals( that.entityOrRoleName ) ) {
92+
return false;
93+
}
94+
if ( cacheKeyValueDescriptor == null ) {
95+
if ( !Objects.equals( id, that.id ) ) {
96+
return false;
97+
}
98+
}
99+
else if ( !cacheKeyValueDescriptor.isEqual( id, that.id ) ) {
100+
return false;
101+
}
102+
return Objects.equals( tenantId, that.tenantId );
85103
}
86104

87105
@Override

hibernate-core/src/main/java/org/hibernate/cache/internal/ComponentCacheKeyValueDescriptor.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@
2020
* @see CustomComponentCacheKeyValueDescriptor
2121
*/
2222
public class ComponentCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
23-
private final NavigableRole role;
23+
private final String role;
2424
private final SessionFactoryImplementor sessionFactory;
2525

2626
private transient EmbeddableValuedModelPart embeddedMapping;
2727

28-
public ComponentCacheKeyValueDescriptor(NavigableRole role, SessionFactoryImplementor sessionFactory) {
29-
this.role = role;
28+
public ComponentCacheKeyValueDescriptor(
29+
EmbeddableValuedModelPart embeddedMapping,
30+
SessionFactoryImplementor sessionFactory) {
31+
this.role = embeddedMapping.getNavigableRole().getFullPath();
3032
this.sessionFactory = sessionFactory;
33+
this.embeddedMapping = embeddedMapping;
3134
}
3235

3336
@Override
@@ -82,10 +85,12 @@ public Object getAttributeValue(Object component, int i, AttributeMapping attr)
8285
}
8386
}
8487

85-
8688
private EmbeddableValuedModelPart getEmbeddedMapping() {
89+
EmbeddableValuedModelPart embeddedMapping = this.embeddedMapping;
8790
if ( embeddedMapping == null ) {
88-
embeddedMapping = sessionFactory.getRuntimeMetamodels().getEmbedded( role );
91+
this.embeddedMapping = embeddedMapping = sessionFactory.getRuntimeMetamodels().getEmbedded(
92+
new NavigableRole( role )
93+
);
8994
}
9095
return embeddedMapping;
9196
}

hibernate-core/src/main/java/org/hibernate/cache/internal/CustomComponentCacheKeyValueDescriptor.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,15 @@
66
*/
77
package org.hibernate.cache.internal;
88

9-
import org.hibernate.metamodel.model.domain.NavigableRole;
109
import org.hibernate.usertype.CompositeUserType;
1110

1211
/**
1312
* CacheKeyValueDescriptor used to describe CompositeUserType mappings
1413
*/
1514
public class CustomComponentCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
16-
private final NavigableRole role;
1715
private final CompositeUserType<Object> compositeUserType;
1816

19-
public CustomComponentCacheKeyValueDescriptor(
20-
NavigableRole role,
21-
CompositeUserType<Object> compositeUserType) {
22-
this.role = role;
17+
public CustomComponentCacheKeyValueDescriptor(CompositeUserType<Object> compositeUserType) {
2318
this.compositeUserType = compositeUserType;
2419
}
2520

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

36-
@Override
37-
public String toString() {
38-
return "CustomComponentCacheKeyValueDescriptor(" + role + ")";
39-
}
4031
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.cache.internal;
8+
9+
import java.util.Objects;
10+
11+
public class DefaultCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
12+
public static final DefaultCacheKeyValueDescriptor INSTANCE = new DefaultCacheKeyValueDescriptor();
13+
14+
@Override
15+
public int getHashCode(Object key) {
16+
return key.hashCode();
17+
}
18+
19+
@Override
20+
public boolean isEqual(Object key1, Object key2) {
21+
return Objects.equals( key1, key2 );
22+
}
23+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.cache.internal;
8+
9+
import org.hibernate.type.descriptor.java.JavaType;
10+
11+
public class JavaTypeCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
12+
private final JavaType<Object> javaType;
13+
14+
public JavaTypeCacheKeyValueDescriptor(JavaType<?> javaType) {
15+
//noinspection unchecked
16+
this.javaType = (JavaType<Object>) javaType;
17+
}
18+
19+
@Override
20+
public int getHashCode(Object key) {
21+
return javaType.extractHashCode( key );
22+
}
23+
24+
@Override
25+
public boolean isEqual(Object key1, Object key2) {
26+
return javaType.areEqual( key1, key2 );
27+
}
28+
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,12 @@
6060
* Base support for EmbeddableMappingType implementations
6161
*/
6262
public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType {
63-
protected final SessionFactoryImplementor sessionFactory;
6463

6564
public AbstractEmbeddableMapping(MappingModelCreationProcess creationProcess) {
6665
this( creationProcess.getCreationContext() );
6766
}
6867

6968
public AbstractEmbeddableMapping(RuntimeModelCreationContext creationContext) {
70-
this( creationContext.getSessionFactory() );
71-
}
72-
73-
protected AbstractEmbeddableMapping(SessionFactoryImplementor sessionFactory) {
74-
this.sessionFactory = sessionFactory;
7569
}
7670

7771
@Override

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ private EmbeddableMappingTypeImpl(
143143
this.embeddableJtd = representationStrategy.getMappedJavaType();
144144
this.valueMapping = embeddedPartBuilder.apply( this );
145145

146-
final ConfigurationService cs = sessionFactory.getServiceRegistry()
146+
final ConfigurationService cs = creationContext.getSessionFactory().getServiceRegistry()
147147
.getService(ConfigurationService.class);
148148

149149
this.createEmptyCompositesEnabled = ConfigurationHelper.getBoolean(

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/IdClassEmbeddable.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public IdClassEmbeddable(
8484
this.idMapping = idMapping;
8585
this.virtualIdEmbeddable = virtualIdEmbeddable;
8686

87-
this.javaType = sessionFactory.getTypeConfiguration()
87+
this.javaType = creationProcess.getCreationContext().getSessionFactory().getTypeConfiguration()
8888
.getJavaTypeRegistry()
8989
.resolveManagedTypeDescriptor( idClassSource.getComponentClass() );
9090

@@ -176,7 +176,7 @@ public EmbeddableValuedModelPart getEmbeddedPart() {
176176
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
177177
final Object id = representationStrategy.getInstantiator().instantiate(
178178
null,
179-
sessionFactory
179+
session.getSessionFactory()
180180
);
181181

182182
final List<AttributeMapping> virtualIdAttribute = virtualIdEmbeddable.getAttributeMappings();

hibernate-core/src/main/java/org/hibernate/type/ComponentType.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
6767
private final CompositeUserType<Object> compositeUserType;
6868

6969
private EmbeddableValuedModelPart mappingModelPart;
70-
private CacheKeyValueDescriptor cacheKeyValueDescriptor;
70+
private transient CacheKeyValueDescriptor cacheKeyValueDescriptor;
7171

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

706706
@Override
707707
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
708+
CacheKeyValueDescriptor cacheKeyValueDescriptor = this.cacheKeyValueDescriptor;
708709
if ( cacheKeyValueDescriptor == null ) {
709710
if ( compositeUserType != null ) {
710-
cacheKeyValueDescriptor = new CustomComponentCacheKeyValueDescriptor(
711-
mappingModelPart.getNavigableRole(),
712-
compositeUserType
713-
);
711+
cacheKeyValueDescriptor = new CustomComponentCacheKeyValueDescriptor( compositeUserType );
714712
}
715713
else {
716-
cacheKeyValueDescriptor = new ComponentCacheKeyValueDescriptor(
717-
mappingModelPart.getNavigableRole(),
718-
sessionFactory
719-
);
714+
cacheKeyValueDescriptor = new ComponentCacheKeyValueDescriptor( mappingModelPart, sessionFactory );
720715
}
716+
this.cacheKeyValueDescriptor = cacheKeyValueDescriptor;
721717
}
722718

723719
return cacheKeyValueDescriptor;

hibernate-core/src/main/java/org/hibernate/type/CustomType.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import org.hibernate.HibernateException;
1717
import org.hibernate.MappingException;
18+
import org.hibernate.cache.internal.CacheKeyValueDescriptor;
1819
import org.hibernate.engine.spi.Mapping;
1920
import org.hibernate.engine.spi.SessionFactoryImplementor;
2021
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@@ -66,6 +67,8 @@ public class CustomType<J>
6667
private final ValueBinder<J> valueBinder;
6768
private final JdbcLiteralFormatter<J> jdbcLiteralFormatter;
6869

70+
private transient CacheKeyValueDescriptor cacheKeyValueDescriptor;
71+
6972
public CustomType(UserType<J> userType, TypeConfiguration typeConfiguration) throws MappingException {
7073
this( userType, ArrayHelper.EMPTY_STRING_ARRAY, typeConfiguration );
7174
}
@@ -388,4 +391,32 @@ public JavaType<?> getJdbcJavaType() {
388391
public BasicValueConverter<J, Object> getValueConverter() {
389392
return userType.getValueConverter();
390393
}
394+
395+
@Override
396+
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
397+
CacheKeyValueDescriptor cacheKeyValueDescriptor = this.cacheKeyValueDescriptor;
398+
if ( cacheKeyValueDescriptor == null ) {
399+
this.cacheKeyValueDescriptor = cacheKeyValueDescriptor = new CustomTypeCacheKeyValueDescriptor( getUserType() );
400+
}
401+
return cacheKeyValueDescriptor;
402+
}
403+
404+
private static final class CustomTypeCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
405+
private final UserType<Object> userType;
406+
407+
public CustomTypeCacheKeyValueDescriptor(UserType<?> userType) {
408+
//noinspection unchecked
409+
this.userType = (UserType<Object>) userType;
410+
}
411+
412+
@Override
413+
public int getHashCode(Object key) {
414+
return userType.hashCode( key );
415+
}
416+
417+
@Override
418+
public boolean isEqual(Object key1, Object key2) {
419+
return userType.equals( key1, key2 );
420+
}
421+
}
391422
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigDecimalJavaType.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
import java.math.BigInteger;
1111
import java.util.Locale;
1212

13+
import org.hibernate.cache.internal.CacheKeyValueDescriptor;
1314
import org.hibernate.dialect.Dialect;
15+
import org.hibernate.engine.spi.SessionFactoryImplementor;
1416
import org.hibernate.type.descriptor.WrapperOptions;
1517
import org.hibernate.type.descriptor.jdbc.JdbcType;
1618

@@ -44,6 +46,11 @@ public int extractHashCode(BigDecimal value) {
4446
return value.intValue();
4547
}
4648

49+
@Override
50+
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
51+
return BigNumberCacheKeyValueDescriptor.INSTANCE;
52+
}
53+
4754
@SuppressWarnings("unchecked")
4855
public <X> X unwrap(BigDecimal value, Class<X> type, WrapperOptions options) {
4956
if ( value == null ) {

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigIntegerJavaType.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
import java.math.BigInteger;
1111
import java.util.Locale;
1212

13+
import org.hibernate.cache.internal.CacheKeyValueDescriptor;
1314
import org.hibernate.dialect.Dialect;
15+
import org.hibernate.engine.spi.SessionFactoryImplementor;
1416
import org.hibernate.type.descriptor.WrapperOptions;
1517
import org.hibernate.type.descriptor.jdbc.JdbcType;
1618

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

51+
@Override
52+
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
53+
return BigNumberCacheKeyValueDescriptor.INSTANCE;
54+
}
55+
4956
@Override
5057
@SuppressWarnings("unchecked")
5158
public <X> X unwrap(BigInteger value, Class<X> type, WrapperOptions options) {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.type.descriptor.java;
8+
9+
import org.hibernate.cache.internal.CacheKeyValueDescriptor;
10+
11+
final class BigNumberCacheKeyValueDescriptor implements CacheKeyValueDescriptor {
12+
static final BigNumberCacheKeyValueDescriptor INSTANCE = new BigNumberCacheKeyValueDescriptor();
13+
14+
@Override
15+
public int getHashCode(Object key) {
16+
return ( (Number) key ).intValue();
17+
}
18+
19+
@Override
20+
public boolean isEqual(Object key1, Object key2) {
21+
//noinspection unchecked
22+
return ( key1 == key2 ) || ( key1 != null && key2 != null && ( (Comparable<Object>) key1 ).compareTo( key2 ) == 0 );
23+
}
24+
}

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanJavaType.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
*/
77
package org.hibernate.type.descriptor.java;
88

9+
import org.hibernate.cache.internal.CacheKeyValueDescriptor;
10+
import org.hibernate.cache.internal.DefaultCacheKeyValueDescriptor;
911
import org.hibernate.dialect.Dialect;
12+
import org.hibernate.engine.spi.SessionFactoryImplementor;
1013
import org.hibernate.type.descriptor.WrapperOptions;
1114
import org.hibernate.type.descriptor.java.spi.PrimitiveJavaType;
1215
import org.hibernate.type.descriptor.jdbc.JdbcType;
@@ -177,4 +180,9 @@ public String getCheckCondition(String columnName, JdbcType sqlTypeDescriptor, D
177180
);
178181
}
179182

183+
@Override
184+
public CacheKeyValueDescriptor toCacheKeyDescriptor(SessionFactoryImplementor sessionFactory) {
185+
return DefaultCacheKeyValueDescriptor.INSTANCE;
186+
}
187+
180188
}

0 commit comments

Comments
 (0)