HHH-16281 Inconsistent Behaivor of L2 cache between Hibernate 5 and 6
This commit is contained in:
parent
f2be305a43
commit
aafb7cdd45
|
@ -56,7 +56,13 @@ public interface BasicValuedMapping extends ValueMapping, SqlExpressible {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session){
|
default void addToCacheKey(
|
||||||
|
MutableCacheKeyBuilder cacheKey,
|
||||||
|
Object value,
|
||||||
|
SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final JdbcMapping jdbcMapping = getJdbcMapping();
|
final JdbcMapping jdbcMapping = getJdbcMapping();
|
||||||
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
||||||
final Serializable disassemble;
|
final Serializable disassemble;
|
||||||
|
|
|
@ -320,6 +320,9 @@ public class IdClassEmbeddable extends AbstractEmbeddableMapping implements Iden
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final Serializable[] result = new Serializable[ getNumberOfAttributeMappings() ];
|
final Serializable[] result = new Serializable[ getNumberOfAttributeMappings() ];
|
||||||
for ( int i = 0; i < result.length; i++ ) {
|
for ( int i = 0; i < result.length; i++ ) {
|
||||||
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
final AttributeMapping attributeMapping = getAttributeMapping( i );
|
||||||
|
|
|
@ -423,6 +423,9 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final JdbcMapping jdbcMapping = getJdbcMapping();
|
final JdbcMapping jdbcMapping = getJdbcMapping();
|
||||||
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
||||||
final Serializable disassemble;
|
final Serializable disassemble;
|
||||||
|
|
|
@ -44,6 +44,9 @@ public class TupleMappingModelExpressible implements MappingModelExpressible {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for ( int i = 0; i < components.length; i++ ) {
|
for ( int i = 0; i < components.length; i++ ) {
|
||||||
components[i].addToCacheKey( cacheKey, value, session );
|
components[i].addToCacheKey( cacheKey, value, session );
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,6 +317,9 @@ public class AnonymousTupleBasicValuedModelPart implements ModelPart, MappingTyp
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
cacheKey.addValue( value );
|
cacheKey.addValue( value );
|
||||||
cacheKey.addHashCode( ( (JavaType) getExpressibleJavaType() ).extractHashCode( value ) );
|
cacheKey.addHashCode( ( (JavaType) getExpressibleJavaType() ).extractHashCode( value ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,9 @@ public class JdbcLiteral<T> implements Literal, MappingModelExpressible<T>, Doma
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final Serializable disassemble = ( (MutabilityPlan<Object>) jdbcMapping.getJdbcJavaType().getMutabilityPlan() )
|
final Serializable disassemble = ( (MutabilityPlan<Object>) jdbcMapping.getJdbcJavaType().getMutabilityPlan() )
|
||||||
.disassemble( value, session );
|
.disassemble( value, session );
|
||||||
final int hashCode = jdbcMapping.getJavaTypeDescriptor().extractHashCode( value );
|
final int hashCode = jdbcMapping.getJavaTypeDescriptor().extractHashCode( value );
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.exec.internal;
|
package org.hibernate.sql.exec.internal;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
@ -158,20 +159,27 @@ public abstract class AbstractJdbcParameter
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final JdbcMapping jdbcMapping = getJdbcMapping();
|
final JdbcMapping jdbcMapping = getJdbcMapping();
|
||||||
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
||||||
|
|
||||||
|
final Serializable disassemble;
|
||||||
|
final int hashCode;
|
||||||
if ( converter == null ) {
|
if ( converter == null ) {
|
||||||
final JavaType javaTypeDescriptor = jdbcMapping.getJavaTypeDescriptor();
|
final JavaType javaTypeDescriptor = jdbcMapping.getJavaTypeDescriptor();
|
||||||
cacheKey.addValue( javaTypeDescriptor.getMutabilityPlan().disassemble( value, session ) );
|
disassemble = javaTypeDescriptor.getMutabilityPlan().disassemble( value, session );
|
||||||
cacheKey.addHashCode( javaTypeDescriptor.extractHashCode( value ) );
|
hashCode = javaTypeDescriptor.extractHashCode( value );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final Object relationalValue = converter.toRelationalValue( value );
|
final Object relationalValue = converter.toRelationalValue( value );
|
||||||
final JavaType relationalJavaType = converter.getRelationalJavaType();
|
final JavaType relationalJavaType = converter.getRelationalJavaType();
|
||||||
cacheKey.addValue( relationalJavaType.getMutabilityPlan().disassemble( relationalValue, session ) );
|
disassemble = relationalJavaType.getMutabilityPlan().disassemble( relationalValue, session );
|
||||||
cacheKey.addHashCode( relationalJavaType.extractHashCode( relationalValue ) );
|
hashCode = relationalJavaType.extractHashCode( relationalValue );
|
||||||
}
|
}
|
||||||
|
cacheKey.addValue( disassemble );
|
||||||
|
cacheKey.addHashCode( hashCode );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -220,6 +220,9 @@ public class CustomType<J>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final Serializable disassembled = getUserType().disassemble( (J) value );
|
final Serializable disassembled = getUserType().disassemble( (J) value );
|
||||||
// Since UserType#disassemble is an optional operation,
|
// Since UserType#disassemble is an optional operation,
|
||||||
// we have to handle the fact that it could produce a null value,
|
// we have to handle the fact that it could produce a null value,
|
||||||
|
|
|
@ -95,6 +95,44 @@ public class QueryCacheWithObjectParameterTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryWithEmbeddableParameterWithANull(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
evictQueryRegion( session );
|
||||||
|
Query<Parent> queryParent = session.createQuery(
|
||||||
|
"from Parent p where p.address = :address",
|
||||||
|
Parent.class
|
||||||
|
);
|
||||||
|
queryParent.setParameter( "address", new Address( "via Milano", null ) );
|
||||||
|
queryParent.setCacheable( true );
|
||||||
|
|
||||||
|
List<Parent> resultList = queryParent.getResultList();
|
||||||
|
assertThat( resultList ).hasSize( 0 );
|
||||||
|
|
||||||
|
CacheRegionStatistics defaultQueryCacheRegionStatistics = getQueryCacheRegionStatistics( session );
|
||||||
|
assertThat( defaultQueryCacheRegionStatistics.getHitCount() ).isEqualTo( 0 );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
Query<Parent> queryParent = session.createQuery(
|
||||||
|
"from Parent p where p.address = :address",
|
||||||
|
Parent.class
|
||||||
|
);
|
||||||
|
queryParent.setParameter( "address", new Address( "via Milano", null ) );
|
||||||
|
queryParent.setCacheable( true );
|
||||||
|
|
||||||
|
List<Parent> resultList = queryParent.getResultList();
|
||||||
|
assertThat( resultList ).hasSize( 0 );
|
||||||
|
|
||||||
|
CacheRegionStatistics defaultQueryCacheRegionStatistics = getQueryCacheRegionStatistics( session );
|
||||||
|
assertThat( defaultQueryCacheRegionStatistics.getHitCount() ).isEqualTo( 1 );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQueryCacheHits(SessionFactoryScope scope) {
|
public void testQueryCacheHits(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
|
@ -189,6 +227,56 @@ public class QueryCacheWithObjectParameterTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryCacheHitsNullParameter(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
evictQueryRegion( session );
|
||||||
|
Query<Parent> queryParent = session.createQuery(
|
||||||
|
"from Parent p where p.name = 'John'",
|
||||||
|
Parent.class
|
||||||
|
);
|
||||||
|
List<Parent> p = queryParent.getResultList();
|
||||||
|
assertThat( p ).hasSize( 1 );
|
||||||
|
|
||||||
|
Query<Child> queryChildren = session.createQuery(
|
||||||
|
"from Child c where c.parent.id = ?1",
|
||||||
|
Child.class
|
||||||
|
);
|
||||||
|
queryChildren.setParameter( 1, null );
|
||||||
|
queryChildren.setCacheable( true );
|
||||||
|
List<Child> c = queryChildren.getResultList();
|
||||||
|
assertThat( c ).hasSize( 0 );
|
||||||
|
|
||||||
|
CacheRegionStatistics defaultQueryCacheRegionStatistics = getQueryCacheRegionStatistics( session );
|
||||||
|
assertThat( defaultQueryCacheRegionStatistics.getHitCount() ).isEqualTo( 0 );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
Query<Parent> queryParent = session.createQuery(
|
||||||
|
"from Parent p where p.name = 'John'",
|
||||||
|
Parent.class
|
||||||
|
);
|
||||||
|
List<Parent> p = queryParent.getResultList();
|
||||||
|
assertThat( p ).hasSize( 1 );
|
||||||
|
|
||||||
|
Query<Child> queryChildren = session.createQuery(
|
||||||
|
"from Child c where c.parent.id = ?1",
|
||||||
|
Child.class
|
||||||
|
);
|
||||||
|
queryChildren.setParameter( 1, null );
|
||||||
|
queryChildren.setCacheable( true );
|
||||||
|
List<Child> c = queryChildren.getResultList();
|
||||||
|
assertThat( c ).hasSize( 0 );
|
||||||
|
|
||||||
|
CacheRegionStatistics defaultQueryCacheRegionStatistics = getQueryCacheRegionStatistics( session );
|
||||||
|
assertThat( defaultQueryCacheRegionStatistics.getHitCount() ).isEqualTo( 1 );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private static void evictQueryRegion(SessionImplementor session) {
|
private static void evictQueryRegion(SessionImplementor session) {
|
||||||
session.getSessionFactory()
|
session.getSessionFactory()
|
||||||
.getCache()
|
.getCache()
|
||||||
|
|
Loading…
Reference in New Issue