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.QueryParameterBinding;
import org.hibernate.query.spi.QueryParameterBindingValidator; import org.hibernate.query.spi.QueryParameterBindingValidator;
import org.hibernate.query.sqm.SqmExpressible; 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.JavaType;
import org.hibernate.type.descriptor.java.JavaTypeHelper; import org.hibernate.type.descriptor.java.JavaTypeHelper;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
@ -113,10 +114,10 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
final Object coerced; final Object coerced;
if ( ! sessionFactory.getSessionFactoryOptions().getJpaCompliance().isLoadByIdComplianceEnabled() ) { if ( ! sessionFactory.getSessionFactoryOptions().getJpaCompliance().isLoadByIdComplianceEnabled() ) {
try { try {
if ( bindType != null ) { if ( canValueBeCoerced( bindType) ) {
coerced = coerce( value, bindType ); coerced = coerce( value, bindType );
} }
else if ( queryParameter.getHibernateType() != null ) { else if ( canValueBeCoerced( queryParameter.getHibernateType() ) ) {
coerced = coerce( value, queryParameter.getHibernateType() ); coerced = coerce( value, queryParameter.getHibernateType() );
} }
else { else {
@ -190,7 +191,7 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
private void bindValue(Object value) { private void bindValue(Object value) {
isBound = true; isBound = true;
bindValue = value; bindValue = value;
if ( bindType == null && value != null ) { if ( canBindValueBeSet( value, bindType ) ) {
bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value ); bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value );
} }
} }
@ -206,10 +207,10 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
} }
final Object coerced; final Object coerced;
if ( bindType != null ) { if ( canValueBeCoerced( bindType ) ) {
coerced = coerce( value, bindType ); coerced = coerce( value, bindType );
} }
else if ( queryParameter.getHibernateType() != null ) { else if ( canValueBeCoerced( queryParameter.getHibernateType() ) ) {
coerced = coerce( value, queryParameter.getHibernateType() ); coerced = coerce( value, queryParameter.getHibernateType() );
} }
else { else {
@ -233,7 +234,7 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
final Object coerced; final Object coerced;
if ( ! sessionFactory.getSessionFactoryOptions().getJpaCompliance().isLoadByIdComplianceEnabled() ) { if ( ! sessionFactory.getSessionFactoryOptions().getJpaCompliance().isLoadByIdComplianceEnabled() ) {
if ( bindType != null ) { if (canValueBeCoerced( bindType ) ) {
try { try {
coerced = coerce( value, bindType ); 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() ); coerced = coerce( value, queryParameter.getHibernateType() );
} }
else { else {
@ -299,10 +300,9 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
value = iterator.next(); value = iterator.next();
} }
if ( bindType == null && value != null ) { if ( canBindValueBeSet( value, bindType ) ) {
this.bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value ); bindType = sessionFactory.getMappingMetamodel().resolveParameterBindType( value );
} }
} }
@Override @Override
@ -378,4 +378,12 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
public TypeConfiguration getTypeConfiguration() { public TypeConfiguration getTypeConfiguration() {
return sessionFactory.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.criteria.JpaExpression;
import org.hibernate.query.internal.QueryOptionsImpl; import org.hibernate.query.internal.QueryOptionsImpl;
import org.hibernate.query.sqm.SqmExpressible; 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.SqmLiteral;
import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
@ -907,7 +908,7 @@ public abstract class AbstractCommonQueryContract implements CommonQueryContract
final QueryParameter<Object> param = binding.getQueryParameter(); final QueryParameter<Object> param = binding.getQueryParameter();
if ( param.allowsMultiValuedBinding() ) { if ( param.allowsMultiValuedBinding() ) {
final BindableType<?> hibernateType = param.getHibernateType(); 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() ) ) { if ( value instanceof Collection && !isRegisteredAsBasicType( value.getClass() ) ) {
//noinspection rawtypes //noinspection rawtypes
return setParameterList( position, (Collection) value ); return setParameterList( position, (Collection) value );