Skip to content

Commit b781594

Browse files
dreab8beikov
authored andcommitted
HHH-17687 AttributeConverter, query does not use converter to convert 'null' fields
1 parent e4f5926 commit b781594

File tree

7 files changed

+63
-120
lines changed

7 files changed

+63
-120
lines changed

hibernate-core/src/main/java/org/hibernate/engine/internal/CacheHelper.java

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
*/
77
package org.hibernate.engine.internal;
88

9-
import java.io.Serializable;
10-
119
import org.hibernate.cache.MutableCacheKeyBuilder;
1210
import org.hibernate.cache.spi.access.CachedDomainDataAccess;
1311
import org.hibernate.engine.spi.SessionEventListenerManager;
@@ -90,31 +88,29 @@ public static Object fromSharedCache(
9088
}
9189
return cachedValue;
9290
}
93-
9491
public static void addBasicValueToCacheKey(
9592
MutableCacheKeyBuilder cacheKey,
9693
Object value,
9794
JdbcMapping jdbcMapping,
9895
SharedSessionContractImplementor session) {
99-
if ( value == null ) {
100-
cacheKey.addValue( null );
101-
cacheKey.addHashCode( 0 );
102-
return;
103-
}
10496
final BasicValueConverter converter = jdbcMapping.getValueConverter();
105-
final Serializable disassemble;
106-
final int hashCode;
97+
final Object convertedValue;
98+
final JavaType javaType;
10799
if ( converter == null ) {
108-
disassemble = jdbcMapping.getJavaTypeDescriptor().getMutabilityPlan().disassemble( value, session );
109-
hashCode = ( (JavaType) jdbcMapping.getMappedJavaType() ).extractHashCode( value );
100+
javaType = jdbcMapping.getJavaTypeDescriptor();
101+
convertedValue = value;
102+
}
103+
else {
104+
javaType = converter.getRelationalJavaType();
105+
convertedValue = converter.toRelationalValue( value );
106+
}
107+
if ( convertedValue == null ) {
108+
cacheKey.addValue( null );
109+
cacheKey.addHashCode( 0 );
110110
}
111111
else {
112-
final Object relationalValue = converter.toRelationalValue( value );
113-
final JavaType relationalJavaType = converter.getRelationalJavaType();
114-
disassemble = relationalJavaType.getMutabilityPlan().disassemble( relationalValue, session );
115-
hashCode = relationalJavaType.extractHashCode( relationalValue );
112+
cacheKey.addValue( javaType.getMutabilityPlan().disassemble( convertedValue, session ) );
113+
cacheKey.addHashCode( javaType.extractHashCode( convertedValue ) );
116114
}
117-
cacheKey.addValue( disassemble );
118-
cacheKey.addHashCode( hashCode );
119115
}
120116
}

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

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77
package org.hibernate.metamodel.mapping.internal;
88

9-
import java.io.Serializable;
109
import java.util.Collections;
1110
import java.util.List;
1211
import java.util.Locale;
@@ -16,6 +15,7 @@
1615
import org.hibernate.cache.MutableCacheKeyBuilder;
1716
import org.hibernate.engine.FetchStyle;
1817
import org.hibernate.engine.FetchTiming;
18+
import org.hibernate.engine.internal.CacheHelper;
1919
import org.hibernate.engine.spi.SharedSessionContractImplementor;
2020
import org.hibernate.internal.util.IndexedConsumer;
2121
import org.hibernate.metamodel.mapping.AssociationKey;
@@ -57,7 +57,6 @@
5757
import org.hibernate.sql.results.graph.FetchOptions;
5858
import org.hibernate.sql.results.graph.FetchParent;
5959
import org.hibernate.sql.results.graph.basic.BasicResult;
60-
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
6160
import org.hibernate.type.descriptor.java.JavaType;
6261

6362
/**
@@ -468,27 +467,7 @@ public Object disassemble(Object value, SharedSessionContractImplementor session
468467

469468
@Override
470469
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
471-
if ( value == null ) {
472-
return;
473-
}
474-
final JdbcMapping jdbcMapping = getJdbcMapping();
475-
final BasicValueConverter converter = jdbcMapping.getValueConverter();
476-
final Serializable disassemble;
477-
final int hashCode;
478-
if ( converter == null ) {
479-
final JavaType javaTypeDescriptor = jdbcMapping.getJavaTypeDescriptor();
480-
disassemble = javaTypeDescriptor.getMutabilityPlan().disassemble( value, session );
481-
hashCode = javaTypeDescriptor.extractHashCode( disassemble );
482-
}
483-
else {
484-
final Object relationalValue = converter.toRelationalValue( value );
485-
final JavaType relationalJavaType = converter.getRelationalJavaType();
486-
disassemble = relationalJavaType.getMutabilityPlan().disassemble( relationalValue, session );
487-
hashCode = relationalJavaType.extractHashCode( relationalValue );
488-
}
489-
490-
cacheKey.addValue( disassemble );
491-
cacheKey.addHashCode( hashCode );
470+
CacheHelper.addBasicValueToCacheKey( cacheKey, value, getJdbcMapping(), session );
492471
}
493472

494473
@Override

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import org.hibernate.query.sqm.SqmQuerySource;
4545
import org.hibernate.query.sqm.spi.JdbcParameterBySqmParameterAccess;
4646
import org.hibernate.query.sqm.spi.SqmParameterMappingModelResolutionAccess;
47-
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
4847
import org.hibernate.query.sqm.tree.SqmDmlStatement;
4948
import org.hibernate.query.sqm.tree.SqmJoinType;
5049
import org.hibernate.query.sqm.tree.SqmStatement;
@@ -57,12 +56,10 @@
5756
import org.hibernate.query.sqm.tree.from.SqmJoin;
5857
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
5958
import org.hibernate.query.sqm.tree.from.SqmRoot;
60-
import org.hibernate.query.sqm.tree.select.SqmQueryPart;
6159
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
6260
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
6361
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
6462
import org.hibernate.spi.NavigablePath;
65-
import org.hibernate.sql.ast.Clause;
6663
import org.hibernate.sql.ast.SqlTreeCreationException;
6764
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
6865
import org.hibernate.sql.ast.tree.from.TableGroup;
@@ -350,18 +347,6 @@ else if ( domainParamBinding.isMultiValued() ) {
350347
expansionPosition++;
351348
}
352349
}
353-
else if ( domainParamBinding.getBindValue() == null ) {
354-
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
355-
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
356-
for ( int j = 0; j < jdbcParams.size(); j++ ) {
357-
final JdbcParameter jdbcParameter = jdbcParams.get( j );
358-
jdbcParameterBindings.addBinding(
359-
jdbcParameter,
360-
new JdbcParameterBindingImpl( null, null )
361-
);
362-
}
363-
}
364-
}
365350
else {
366351
final JdbcMapping jdbcMapping;
367352
if ( domainParamBinding.getType() instanceof JdbcMapping ) {
@@ -377,7 +362,6 @@ else if ( domainParamBinding.getBindType() instanceof BasicValuedMapping ) {
377362
final BasicValueConverter valueConverter = jdbcMapping == null ? null : jdbcMapping.getValueConverter();
378363
if ( valueConverter != null ) {
379364
final Object convertedValue = valueConverter.toRelationalValue( domainParamBinding.getBindValue() );
380-
381365
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
382366
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
383367
assert jdbcParams.size() == 1;
@@ -387,23 +371,37 @@ else if ( domainParamBinding.getBindType() instanceof BasicValuedMapping ) {
387371
new JdbcParameterBindingImpl( jdbcMapping, convertedValue )
388372
);
389373
}
390-
391-
continue;
392374
}
375+
else {
376+
final Object bindValue = domainParamBinding.getBindValue();
377+
if ( bindValue == null ) {
378+
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
379+
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
380+
for ( int j = 0; j < jdbcParams.size(); j++ ) {
381+
final JdbcParameter jdbcParameter = jdbcParams.get( j );
382+
jdbcParameterBindings.addBinding(
383+
jdbcParameter,
384+
new JdbcParameterBindingImpl( jdbcMapping, bindValue )
385+
);
386+
}
387+
}
388+
}
389+
else {
393390

394-
final Object bindValue = domainParamBinding.getBindValue();
395-
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
396-
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
397-
createValueBindings(
398-
jdbcParameterBindings,
399-
queryParam,
400-
domainParamBinding,
401-
parameterType,
402-
jdbcParams,
403-
bindValue,
404-
tableGroupLocator,
405-
session
406-
);
391+
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
392+
final JdbcParametersList jdbcParams = jdbcParamsBinds.get( i );
393+
createValueBindings(
394+
jdbcParameterBindings,
395+
queryParam,
396+
domainParamBinding,
397+
parameterType,
398+
jdbcParams,
399+
bindValue,
400+
tableGroupLocator,
401+
session
402+
);
403+
}
404+
}
407405
}
408406
}
409407
}

hibernate-core/src/main/java/org/hibernate/sql/exec/internal/AbstractJdbcParameter.java

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
*/
77
package org.hibernate.sql.exec.internal;
88

9-
import java.io.Serializable;
109
import java.sql.PreparedStatement;
1110
import java.sql.SQLException;
1211

1312
import org.hibernate.cache.MutableCacheKeyBuilder;
13+
import org.hibernate.engine.internal.CacheHelper;
1414
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1515
import org.hibernate.internal.util.IndexedConsumer;
1616
import org.hibernate.metamodel.mapping.BasicValuedMapping;
@@ -29,7 +29,6 @@
2929
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
3030
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
3131
import org.hibernate.sql.results.internal.SqlSelectionImpl;
32-
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
3332
import org.hibernate.type.descriptor.java.EnumJavaType;
3433
import org.hibernate.type.descriptor.java.JavaType;
3534
import org.hibernate.type.descriptor.jdbc.JdbcType;
@@ -188,27 +187,7 @@ public Object disassemble(Object value, SharedSessionContractImplementor session
188187

189188
@Override
190189
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
191-
if ( value == null ) {
192-
return;
193-
}
194-
final JdbcMapping jdbcMapping = getJdbcMapping();
195-
final BasicValueConverter converter = jdbcMapping.getValueConverter();
196-
197-
final Serializable disassemble;
198-
final int hashCode;
199-
if ( converter == null ) {
200-
final JavaType javaTypeDescriptor = jdbcMapping.getJavaTypeDescriptor();
201-
disassemble = javaTypeDescriptor.getMutabilityPlan().disassemble( value, session );
202-
hashCode = javaTypeDescriptor.extractHashCode( value );
203-
}
204-
else {
205-
final Object relationalValue = converter.toRelationalValue( value );
206-
final JavaType relationalJavaType = converter.getRelationalJavaType();
207-
disassemble = relationalJavaType.getMutabilityPlan().disassemble( relationalValue, session );
208-
hashCode = relationalJavaType.extractHashCode( relationalValue );
209-
}
210-
cacheKey.addValue( disassemble );
211-
cacheKey.addHashCode( hashCode );
190+
CacheHelper.addBasicValueToCacheKey( cacheKey, value, getJdbcMapping(), session );
212191
}
213192

214193
@Override

hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingsImpl.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.hibernate.dialect.Dialect;
1717
import org.hibernate.engine.spi.SessionFactoryImplementor;
1818
import org.hibernate.metamodel.mapping.BasicValuedMapping;
19-
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
2019
import org.hibernate.metamodel.mapping.JdbcMapping;
2120
import org.hibernate.query.BindableType;
2221
import org.hibernate.query.spi.QueryParameterBinding;
@@ -94,7 +93,7 @@ else if ( type instanceof BasicValuedMapping ) {
9493
for ( Object bindValue : bindValues ) {
9594
final JdbcParameterImpl jdbcParameter = new JdbcParameterImpl( jdbcMapping );
9695
jdbcParameterBinders.add( jdbcParameter );
97-
lastBindValue = bindValue == null ? null : valueConverter.toRelationalValue( bindValue );
96+
lastBindValue = valueConverter.toRelationalValue( bindValue );
9897
addBinding( jdbcParameter, new JdbcParameterBindingImpl( jdbcMapping, lastBindValue ) );
9998
}
10099
if ( bindValueMaxCount != bindValueCount ) {

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

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.hibernate.HibernateException;
1717
import org.hibernate.MappingException;
1818
import org.hibernate.cache.MutableCacheKeyBuilder;
19+
import org.hibernate.engine.internal.CacheHelper;
1920
import org.hibernate.engine.spi.Mapping;
2021
import org.hibernate.engine.spi.SessionFactoryImplementor;
2122
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@@ -205,7 +206,7 @@ private Serializable disassembleForCache(Object value) {
205206
// we have to handle the fact that it could produce a null value,
206207
// in which case we will try to use a converter for disassembling,
207208
// or if that doesn't exist, simply use the domain value as is
208-
if ( disassembled == null && value != null ) {
209+
if ( disassembled == null ){
209210
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
210211
if ( valueConverter == null ) {
211212
return disassembled;
@@ -220,46 +221,35 @@ private Serializable disassembleForCache(Object value) {
220221
@Override
221222
public Object disassemble(Object value, SharedSessionContractImplementor session) {
222223
// Use the value converter if available for conversion to the jdbc representation
223-
if ( value != null ) {
224224
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
225225
if ( valueConverter == null ) {
226226
return value;
227227
}
228228
else {
229229
return valueConverter.toRelationalValue( (J) value );
230230
}
231-
}
232-
return value;
233231
}
234232

235233
@Override
236234
public void addToCacheKey(MutableCacheKeyBuilder cacheKey, Object value, SharedSessionContractImplementor session) {
237-
if ( value == null ) {
238-
return;
239-
}
235+
240236
final Serializable disassembled = getUserType().disassemble( (J) value );
241237
// Since UserType#disassemble is an optional operation,
242238
// we have to handle the fact that it could produce a null value,
243239
// in which case we will try to use a converter for disassembling,
244240
// or if that doesn't exist, simply use the domain value as is
245-
if ( disassembled == null && value != null ) {
246-
final BasicValueConverter<J, Object> valueConverter = getUserType().getValueConverter();
247-
if ( valueConverter == null ) {
248-
cacheKey.addValue( value );
249-
}
250-
else {
251-
cacheKey.addValue(
252-
valueConverter.getRelationalJavaType().getMutabilityPlan().disassemble(
253-
valueConverter.toRelationalValue( (J) value ),
254-
session
255-
)
256-
);
257-
}
241+
if ( disassembled == null) {
242+
CacheHelper.addBasicValueToCacheKey( cacheKey, value, this, session );
258243
}
259244
else {
260245
cacheKey.addValue( disassembled );
246+
if ( value == null ) {
247+
cacheKey.addHashCode( 0 );
248+
}
249+
else {
250+
cacheKey.addHashCode( getUserType().hashCode( (J) value ) );
251+
}
261252
}
262-
cacheKey.addHashCode( getUserType().hashCode( (J) value ) );
263253
}
264254

265255
@Override

hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/spi/BasicValueConverter.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import org.hibernate.type.descriptor.java.JavaType;
1212
import org.hibernate.type.descriptor.jdbc.JdbcType;
1313

14+
import org.checkerframework.checker.nullness.qual.Nullable;
15+
1416
/**
1517
* Support for {@linkplain org.hibernate.type basic-typed} value conversions.
1618
* <p>
@@ -30,13 +32,13 @@ public interface BasicValueConverter<D,R> {
3032
* Convert the relational form just retrieved from JDBC ResultSet into
3133
* the domain form.
3234
*/
33-
D toDomainValue(R relationalForm);
35+
@Nullable D toDomainValue(@Nullable R relationalForm);
3436

3537
/**
3638
* Convert the domain form into the relational form in preparation for
3739
* storage into JDBC
3840
*/
39-
R toRelationalValue(D domainForm);
41+
@Nullable R toRelationalValue(@Nullable D domainForm);
4042

4143
/**
4244
* Descriptor for the Java type for the domain portion of this converter

0 commit comments

Comments
 (0)