HHH-17687 AttributeConverter, query does not use converter to convert 'null' fields
This commit is contained in:
parent
f29cf88748
commit
6b78d0cf43
|
@ -6,8 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.engine.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.cache.MutableCacheKeyBuilder;
|
||||
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
|
||||
import org.hibernate.engine.spi.SessionEventListenerManager;
|
||||
|
@ -90,31 +88,29 @@ public final class CacheHelper {
|
|||
}
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
public static void addBasicValueToCacheKey(
|
||||
MutableCacheKeyBuilder cacheKey,
|
||||
Object value,
|
||||
JdbcMapping jdbcMapping,
|
||||
SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
cacheKey.addValue( null );
|
||||
cacheKey.addHashCode( 0 );
|
||||
return;
|
||||
}
|
||||
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
||||
final Serializable disassemble;
|
||||
final int hashCode;
|
||||
final Object convertedValue;
|
||||
final JavaType javaType;
|
||||
if ( converter == null ) {
|
||||
disassemble = jdbcMapping.getJavaTypeDescriptor().getMutabilityPlan().disassemble( value, session );
|
||||
hashCode = ( (JavaType) jdbcMapping.getMappedJavaType() ).extractHashCode( value );
|
||||
javaType = jdbcMapping.getJavaTypeDescriptor();
|
||||
convertedValue = value;
|
||||
}
|
||||
else {
|
||||
final Object relationalValue = converter.toRelationalValue( value );
|
||||
final JavaType relationalJavaType = converter.getRelationalJavaType();
|
||||
disassemble = relationalJavaType.getMutabilityPlan().disassemble( relationalValue, session );
|
||||
hashCode = relationalJavaType.extractHashCode( relationalValue );
|
||||
javaType = converter.getRelationalJavaType();
|
||||
convertedValue = converter.toRelationalValue( value );
|
||||
}
|
||||
if ( convertedValue == null ) {
|
||||
cacheKey.addValue( null );
|
||||
cacheKey.addHashCode( 0 );
|
||||
}
|
||||
else {
|
||||
cacheKey.addValue( javaType.getMutabilityPlan().disassemble( convertedValue, session ) );
|
||||
cacheKey.addHashCode( javaType.extractHashCode( convertedValue ) );
|
||||
}
|
||||
cacheKey.addValue( disassemble );
|
||||
cacheKey.addHashCode( hashCode );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -16,6 +15,7 @@ import java.util.function.IntFunction;
|
|||
import org.hibernate.cache.MutableCacheKeyBuilder;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.internal.CacheHelper;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.IndexedConsumer;
|
||||
import org.hibernate.metamodel.mapping.AssociationKey;
|
||||
|
@ -57,7 +57,6 @@ import org.hibernate.sql.results.graph.Fetch;
|
|||
import org.hibernate.sql.results.graph.FetchOptions;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
|
@ -468,27 +467,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
|||
|
||||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return;
|
||||
}
|
||||
final JdbcMapping jdbcMapping = getJdbcMapping();
|
||||
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
||||
final Serializable disassemble;
|
||||
final int hashCode;
|
||||
if ( converter == null ) {
|
||||
final JavaType javaTypeDescriptor = jdbcMapping.getJavaTypeDescriptor();
|
||||
disassemble = javaTypeDescriptor.getMutabilityPlan().disassemble( value, session );
|
||||
hashCode = javaTypeDescriptor.extractHashCode( disassemble );
|
||||
}
|
||||
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 );
|
||||
CacheHelper.addBasicValueToCacheKey( cacheKey, value, getJdbcMapping(), session );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.hibernate.query.sqm.NodeBuilder;
|
|||
import org.hibernate.query.sqm.SqmQuerySource;
|
||||
import org.hibernate.query.sqm.spi.JdbcParameterBySqmParameterAccess;
|
||||
import org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.SqmDmlStatement;
|
||||
import org.hibernate.query.sqm.tree.SqmJoinType;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
|
@ -57,12 +56,10 @@ import org.hibernate.query.sqm.tree.from.SqmFrom;
|
|||
import org.hibernate.query.sqm.tree.from.SqmJoin;
|
||||
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
|
||||
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
||||
import org.hibernate.query.sqm.tree.select.SqmQueryPart;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.SqlTreeCreationException;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
|
@ -350,18 +347,6 @@ public class SqmUtil {
|
|||
expansionPosition++;
|
||||
}
|
||||
}
|
||||
else if ( domainParamBinding.getBindValue() == null ) {
|
||||
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
|
||||
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
|
||||
for ( int j = 0; j < jdbcParams.size(); j++ ) {
|
||||
final JdbcParameter jdbcParameter = jdbcParams.get( j );
|
||||
jdbcParameterBindings.addBinding(
|
||||
jdbcParameter,
|
||||
new JdbcParameterBindingImpl( null, null )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final JdbcMapping jdbcMapping;
|
||||
if ( domainParamBinding.getType() instanceof JdbcMapping ) {
|
||||
|
@ -377,7 +362,6 @@ public class SqmUtil {
|
|||
final BasicValueConverter valueConverter = jdbcMapping == null ? null : jdbcMapping.getValueConverter();
|
||||
if ( valueConverter != null ) {
|
||||
final Object convertedValue = valueConverter.toRelationalValue( domainParamBinding.getBindValue() );
|
||||
|
||||
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
|
||||
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
|
||||
assert jdbcParams.size() == 1;
|
||||
|
@ -387,23 +371,37 @@ public class SqmUtil {
|
|||
new JdbcParameterBindingImpl( jdbcMapping, convertedValue )
|
||||
);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
final Object bindValue = domainParamBinding.getBindValue();
|
||||
if ( bindValue == null ) {
|
||||
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
|
||||
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
|
||||
for ( int j = 0; j < jdbcParams.size(); j++ ) {
|
||||
final JdbcParameter jdbcParameter = jdbcParams.get( j );
|
||||
jdbcParameterBindings.addBinding(
|
||||
jdbcParameter,
|
||||
new JdbcParameterBindingImpl( jdbcMapping, bindValue )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
final Object bindValue = domainParamBinding.getBindValue();
|
||||
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
|
||||
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
|
||||
createValueBindings(
|
||||
jdbcParameterBindings,
|
||||
queryParam,
|
||||
domainParamBinding,
|
||||
parameterType,
|
||||
jdbcParams,
|
||||
bindValue,
|
||||
tableGroupLocator,
|
||||
session
|
||||
);
|
||||
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
|
||||
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
|
||||
createValueBindings(
|
||||
jdbcParameterBindings,
|
||||
queryParam,
|
||||
domainParamBinding,
|
||||
parameterType,
|
||||
jdbcParams,
|
||||
bindValue,
|
||||
tableGroupLocator,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
*/
|
||||
package org.hibernate.sql.exec.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.cache.MutableCacheKeyBuilder;
|
||||
import org.hibernate.engine.internal.CacheHelper;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.IndexedConsumer;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
|
@ -29,7 +29,6 @@ import org.hibernate.sql.exec.spi.JdbcParameterBinder;
|
|||
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
|
||||
import org.hibernate.type.descriptor.java.EnumJavaType;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
@ -188,27 +187,7 @@ public abstract class AbstractJdbcParameter
|
|||
|
||||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return;
|
||||
}
|
||||
final JdbcMapping jdbcMapping = getJdbcMapping();
|
||||
final BasicValueConverter converter = jdbcMapping.getValueConverter();
|
||||
|
||||
final Serializable disassemble;
|
||||
final int hashCode;
|
||||
if ( converter == null ) {
|
||||
final JavaType javaTypeDescriptor = jdbcMapping.getJavaTypeDescriptor();
|
||||
disassemble = javaTypeDescriptor.getMutabilityPlan().disassemble( value, session );
|
||||
hashCode = javaTypeDescriptor.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 );
|
||||
CacheHelper.addBasicValueToCacheKey( cacheKey, value, getJdbcMapping(), session );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.function.BiConsumer;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.spi.QueryParameterBinding;
|
||||
|
@ -94,7 +93,7 @@ public class JdbcParameterBindingsImpl implements JdbcParameterBindings {
|
|||
for ( Object bindValue : bindValues ) {
|
||||
final JdbcParameterImpl jdbcParameter = new JdbcParameterImpl( jdbcMapping );
|
||||
jdbcParameterBinders.add( jdbcParameter );
|
||||
lastBindValue = bindValue == null ? null : valueConverter.toRelationalValue( bindValue );
|
||||
lastBindValue = valueConverter.toRelationalValue( bindValue );
|
||||
addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, lastBindValue ) );
|
||||
}
|
||||
if ( bindValueMaxCount != bindValueCount ) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.Map;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.cache.MutableCacheKeyBuilder;
|
||||
import org.hibernate.engine.internal.CacheHelper;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
@ -205,7 +206,7 @@ public class CustomType<J>
|
|||
// we have to handle the fact that it could produce a null value,
|
||||
// in which case we will try to use a converter for disassembling,
|
||||
// or if that doesn't exist, simply use the domain value as is
|
||||
if ( disassembled == null && value != null ) {
|
||||
if ( disassembled == null ){
|
||||
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
|
||||
if ( valueConverter == null ) {
|
||||
return disassembled;
|
||||
|
@ -220,7 +221,6 @@ public class CustomType<J>
|
|||
@Override
|
||||
public Object disassemble(Object value, SharedSessionContractImplementor session) {
|
||||
// Use the value converter if available for conversion to the jdbc representation
|
||||
if ( value != null ) {
|
||||
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
|
||||
if ( valueConverter == null ) {
|
||||
return value;
|
||||
|
@ -228,38 +228,28 @@ public class CustomType<J>
|
|||
else {
|
||||
return valueConverter.toRelationalValue( (J) value );
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
|
||||
if ( value == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Serializable disassembled = getUserType().disassemble( (J) value );
|
||||
// Since UserType#disassemble is an optional operation,
|
||||
// we have to handle the fact that it could produce a null value,
|
||||
// in which case we will try to use a converter for disassembling,
|
||||
// or if that doesn't exist, simply use the domain value as is
|
||||
if ( disassembled == null && value != null ) {
|
||||
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
|
||||
if ( valueConverter == null ) {
|
||||
cacheKey.addValue( value );
|
||||
}
|
||||
else {
|
||||
cacheKey.addValue(
|
||||
valueConverter.getRelationalJavaType().getMutabilityPlan().disassemble(
|
||||
valueConverter.toRelationalValue( (J) value ),
|
||||
session
|
||||
)
|
||||
);
|
||||
}
|
||||
if ( disassembled == null) {
|
||||
CacheHelper.addBasicValueToCacheKey( cacheKey, value, this, session );
|
||||
}
|
||||
else {
|
||||
cacheKey.addValue( disassembled );
|
||||
if ( value == null ) {
|
||||
cacheKey.addHashCode( 0 );
|
||||
}
|
||||
else {
|
||||
cacheKey.addHashCode( getUserType().hashCode( (J) value ) );
|
||||
}
|
||||
}
|
||||
cacheKey.addHashCode( getUserType().hashCode( (J) value ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,6 +11,8 @@ import org.hibernate.dialect.Dialect;
|
|||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Support for {@linkplain org.hibernate.type basic-typed} value conversions.
|
||||
* <p>
|
||||
|
@ -30,13 +32,13 @@ public interface BasicValueConverter<D,R> {
|
|||
* Convert the relational form just retrieved from JDBC ResultSet into
|
||||
* the domain form.
|
||||
*/
|
||||
D toDomainValue(R relationalForm);
|
||||
@Nullable D toDomainValue(@Nullable R relationalForm);
|
||||
|
||||
/**
|
||||
* Convert the domain form into the relational form in preparation for
|
||||
* storage into JDBC
|
||||
*/
|
||||
R toRelationalValue(D domainForm);
|
||||
@Nullable R toRelationalValue(@Nullable D domainForm);
|
||||
|
||||
/**
|
||||
* Descriptor for the Java type for the domain portion of this converter
|
||||
|
|
Loading…
Reference in New Issue