Skip to content

Commit

Permalink
HHH-16281 Inconsistent Behaivor of L2 cache between Hibernate 5 and 6
Browse files Browse the repository at this point in the history
  • Loading branch information
dreab8 authored and beikov committed Mar 24, 2023
1 parent 33fb2a7 commit 71373eb
Show file tree
Hide file tree
Showing 44 changed files with 465 additions and 154 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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;

import java.io.Serializable;

import org.hibernate.cache.spi.QueryResultsCache;

/**
* A builder that generates a Serializable Object to be used as a key into the {@linkplain QueryResultsCache
* query results cache}.
*/

public interface MutableCacheKeyBuilder extends Serializable {

void addValue(Object value);


void addHashCode(int hashCode);

/**
* creates an Object to be used as a key into the {@linkplain QueryResultsCache
* query results cache}.
*/
Serializable build();

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
*/
package org.hibernate.metamodel.mapping;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.JavaType;

/**
* Any basic-typed ValueMapping. Generally this would be one of<ul>
* <li>a {@link jakarta.persistence.Basic} attribute</li>
Expand Down Expand Up @@ -43,4 +49,29 @@ default JdbcMapping getSingleJdbcMapping() {
}

JdbcMapping getJdbcMapping();

@Override
default Object disassemble(Object value, SharedSessionContractImplementor session) {
return getJdbcMapping().convertToRelationalValue( value );
}

@Override
default void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session){
final JdbcMapping jdbcMapping = getJdbcMapping();
final BasicValueConverter converter = jdbcMapping.getValueConverter();
final Serializable disassemble;
final int hashCode;
if ( converter == null ) {
disassemble = jdbcMapping.getJavaTypeDescriptor().getMutabilityPlan().disassemble( value, session );
hashCode = ( (JavaType) jdbcMapping.getMappedJavaType() ).extractHashCode( value );
}
else {
final Object relationalValue = converter.toRelationalValue( value );
final JavaType relationalJavaType = converter.getRelationalJavaType();
disassemble = relationalJavaType.getMutabilityPlan().disassemble( relationalValue, session );
hashCode = relationalJavaType.extractHashCode( relationalValue );
}
cacheKey.addValue( disassemble );
cacheKey.addHashCode( hashCode );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.List;

import org.hibernate.Incubating;
import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;

Expand Down Expand Up @@ -51,52 +52,56 @@ default int forEachJdbcType(IndexedConsumer<JdbcMapping> action) {
}

/**
* @asciidoc
*
* Breaks down a value of `J` into its simple pieces. E.g., an embedded
* @asciidoc Breaks down a value of `J` into its simple pieces. E.g., an embedded
* value gets broken down into an array of its attribute state; a basic
* value converts to itself; etc.
* <p>
* Generally speaking, this is the form in which entity state is kept relative to a
* Session via `EntityEntry`.
*
* @see org.hibernate.engine.spi.EntityEntry
*
* As an example, consider the following domain model:
*
* ````
* @Entity
* class Person {
* @Id Integer id;
* @Embedded Name name;
* int age;
* @Entity class Person {
* @Id Integer id;
* @Embedded Name name;
* int age;
* }
*
* @Embeddable
* class Name {
* String familiarName;
* String familyName;
* @Embeddable class Name {
* String familiarName;
* String familyName;
* }
* ````
*
* <p>
* At the top-level, we would want to disassemble a `Person` value so we'd ask the
* `Bindable` for the `Person` entity to disassemble. Given a Person value:
*
* <p>
* ````
* Person( id=1, name=Name( 'Steve', 'Ebersole' ), 28 )
* ````
*
* <p>
* this disassemble would result in a multi-dimensional array:
*
* <p>
* ````
* [ ["Steve", "Ebersole"], 28 ]
* ````
*
* <p>
* Note that the identifier is not part of this disassembled state. Note also
* how the embedded value results in a sub-array.
* @see org.hibernate.engine.spi.EntityEntry
* <p>
* As an example, consider the following domain model:
* <p>
* ````
*/
Object disassemble(Object value, SharedSessionContractImplementor session);

/**
* Add to the MutableCacheKey the values obtained disassembling the value and the hasCode generated from
* the disassembled value.
*
* @param cacheKey the MutableCacheKey used to add the disassembled value and the hashCode
* @param value the value to disassemble
* @param session the SharedSessionContractImplementor
*/
void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session);

/**
* @asciidoc
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;
import java.util.function.Consumer;

import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.property.access.spi.PropertyAccess;
Expand Down Expand Up @@ -115,6 +116,11 @@ default Object disassemble(Object value, SharedSessionContractImplementor sessio
return getEmbeddableTypeDescriptor().disassemble( value, session );
}

@Override
default void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
getEmbeddableTypeDescriptor().addToCacheKey( cacheKey, value, session );
}

/**
* @see org.hibernate.annotations.Parent
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.spi.NavigablePath;
Expand Down Expand Up @@ -100,6 +101,11 @@ default Object disassemble(Object value, SharedSessionContractImplementor sessio
return getEntityMappingType().disassemble( value, session );
}

@Override
default void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session){
getEntityMappingType().addToCacheKey( cacheKey, value, session );
}

@Override
default <X, Y> int forEachDisassembledJdbcValue(
Object value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.hibernate.MappingException;
import org.hibernate.SharedSessionContract;
import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
Expand Down Expand Up @@ -575,18 +576,26 @@ public void visitSubParts(Consumer<ModelPart> consumer, EntityMappingType treatT

@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
final MutableAttributeMappingList attributes = attributeMappings;
final int size = attributes.size();
final int size = attributeMappings.size();
final Object[] result = new Object[ size ];
for ( int i = 0; i < size; i++ ) {
final AttributeMapping attributeMapping = attributes.get( i );
final AttributeMapping attributeMapping = attributeMappings.get( i );
final Object o = attributeMapping.getValue( value );
result[i] = attributeMapping.disassemble( o, session );
}

return result;
}

@Override
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
final int size = attributeMappings.size();
for ( int i = 0; i < size; i++ ) {
final AttributeMapping attributeMapping = attributeMappings.get( i );
attributeMapping.addToCacheKey( cacheKey, attributeMapping.getValue( value ), session );
}
}

@Override
public <X, Y> int forEachDisassembledJdbcValue(
Object value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
*/
package org.hibernate.metamodel.mapping.internal;

import java.io.Serializable;
import java.util.function.BiConsumer;

import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
Expand Down Expand Up @@ -209,8 +209,13 @@ public void applySqlSelections(

@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
final Serializable discriminator = metaType.disassemble( value, session, value );
return discriminator;
return metaType.disassemble( value, session, value );
}

@Override
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
cacheKey.addValue( metaType.disassemble( value, session, value ) );
cacheKey.addHashCode( metaType.getHashCode( value ) );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.hibernate.metamodel.mapping.internal;

import java.io.Serializable;
import java.util.function.BiConsumer;

import org.hibernate.engine.FetchStyle;
Expand Down Expand Up @@ -393,11 +394,6 @@ public Fetch generateFetch(
);
}

@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return jdbcMapping.convertToRelationalValue( value );
}

@Override
public <X, Y> int forEachDisassembledJdbcValue(
Object value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.function.BiConsumer;
import java.util.function.Supplier;

import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.internal.UnsavedValueFactory;
Expand Down Expand Up @@ -382,6 +383,11 @@ public Object disassemble(Object value, SharedSessionContractImplementor session
return idType.disassemble( value, session );
}

@Override
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
idType.addToCacheKey( cacheKey, value, session );
}

@Override
public <X, Y> int forEachDisassembledJdbcValue(
Object value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.hibernate.metamodel.mapping.internal;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -357,9 +358,4 @@ public <X, Y> int forEachDisassembledJdbcValue(
valuesConsumer.consume( offset, x, y, value, getJdbcMapping() );
return getJdbcTypeCount();
}

@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return selectableMapping.getJdbcMapping().convertToRelationalValue( value );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.function.BiConsumer;

import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
Expand Down Expand Up @@ -323,6 +324,11 @@ public Object disassemble(Object value, SharedSessionContractImplementor session
return type.disassemble( value, session );
}

@Override
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
type.addToCacheKey( cacheKey, value, session );
}

@Override
public <X, Y> int forEachDisassembledJdbcValue(
Object value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.function.Consumer;

import org.hibernate.HibernateException;
import org.hibernate.cache.MutableCacheKeyBuilder;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
Expand Down Expand Up @@ -393,6 +394,18 @@ public Object disassemble(Object value, SharedSessionContractImplementor session
return outgoing;
}

@Override
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
assert value instanceof Object[];

final Object[] values = (Object[]) value;
assert values.length == attributes.size();

for ( int i = 0; i < attributes.size(); i++ ) {
attributes.get( i ).addToCacheKey( cacheKey, values[i], session );
}
}

@Override
public <X, Y> int forEachDisassembledJdbcValue(
Object value,
Expand Down

0 comments on commit 71373eb

Please sign in to comment.