HHH-18556 Expressions.nullExpresion() in querydsl result in NPE in SqmExpressible

This commit is contained in:
Andrea Boriero 2024-09-11 15:44:25 +02:00 committed by Andrea Boriero
parent c56d413bf2
commit 952cf531cf
2 changed files with 20 additions and 11 deletions

View File

@ -20,6 +20,7 @@ import org.hibernate.query.QueryParameter;
import org.hibernate.query.spi.QueryParameterBinding;
import org.hibernate.query.spi.QueryParameterBindingValidator;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.tree.expression.NullSqmExpressible;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.JavaTypeHelper;
import org.hibernate.type.spi.TypeConfiguration;
@ -113,10 +114,10 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
final Object coerced;
if ( ! sessionFactory.getSessionFactoryOptions().getJpaCompliance().isLoadByIdComplianceEnabled() ) {
try {
if ( bindType != null ) {
if ( canValueBeCoerced( bindType) ) {
coerced = coerce( value, bindType );
}
else if ( queryParameter.getHibernateType() != null ) {
else if ( canValueBeCoerced( queryParameter.getHibernateType() ) ) {
coerced = coerce( value, queryParameter.getHibernateType() );
}
else {
@ -190,7 +191,7 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
private void bindValue(Object value) {
isBound = true;
bindValue = value;
if ( bindType == null && value != null ) {
if ( canBindValueBeSet( value, bindType ) ) {
bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value );
}
}
@ -206,10 +207,10 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
}
final Object coerced;
if ( bindType != null ) {
if ( canValueBeCoerced( bindType ) ) {
coerced = coerce( value, bindType );
}
else if ( queryParameter.getHibernateType() != null ) {
else if ( canValueBeCoerced( queryParameter.getHibernateType() ) ) {
coerced = coerce( value, queryParameter.getHibernateType() );
}
else {
@ -233,7 +234,7 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
final Object coerced;
if ( ! sessionFactory.getSessionFactoryOptions().getJpaCompliance().isLoadByIdComplianceEnabled() ) {
if ( bindType != null ) {
if (canValueBeCoerced( bindType ) ) {
try {
coerced = coerce( value, bindType );
}
@ -249,7 +250,7 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
);
}
}
else if ( queryParameter.getHibernateType() != null ) {
else if ( canValueBeCoerced( queryParameter.getHibernateType() ) ) {
coerced = coerce( value, queryParameter.getHibernateType() );
}
else {
@ -299,10 +300,9 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
value = iterator.next();
}
if ( bindType == null && value != null ) {
this.bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value );
if ( canBindValueBeSet( value, bindType ) ) {
bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value );
}
}
@Override
@ -378,4 +378,12 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
public TypeConfiguration getTypeConfiguration() {
return sessionFactory.getTypeConfiguration();
}
private static boolean canValueBeCoerced(BindableType<?> bindType) {
return bindType != null && !( bindType instanceof NullSqmExpressible );
}
private static boolean canBindValueBeSet(Object value, BindableType<?> bindType) {
return value != null && ( bindType == null || bindType instanceof NullSqmExpressible );
}
}

View File

@ -45,6 +45,7 @@ import org.hibernate.query.TypedParameterValue;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.internal.QueryOptionsImpl;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.tree.expression.NullSqmExpressible;
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
@ -907,7 +908,7 @@ public abstract class AbstractCommonQueryContract implements CommonQueryContract
final QueryParameter<Object> param = binding.getQueryParameter();
if ( param.allowsMultiValuedBinding() ) {
final BindableType<?> hibernateType = param.getHibernateType();
if ( hibernateType == null || isInstance( hibernateType, value ) ) {
if ( hibernateType == null || hibernateType instanceof NullSqmExpressible || isInstance( hibernateType, value ) ) {
if ( value instanceof Collection && !isRegisteredAsBasicType( value.getClass() ) ) {
//noinspection rawtypes
return setParameterList( position, (Collection) value );