HHH-17006 fix HQL ':enumValue is null'

This commit is contained in:
Gavin King 2023-07-28 23:36:59 +02:00
parent c74d6fa86f
commit ed88d050f8
3 changed files with 25 additions and 18 deletions

View File

@ -9,10 +9,6 @@ package org.hibernate.internal;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.query.BindableType;
import org.hibernate.query.spi.QueryParameterBindingTypeResolver;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.internal.BasicTypeImpl;
import java.io.Serializable;
@ -36,7 +32,7 @@ public abstract class QueryParameterBindingTypeResolverImpl implements QueryPara
return getMappingMetamodel().resolveQueryParameterType( javaType );
}
@Override @SuppressWarnings({"rawtypes", "unchecked"})
@Override @SuppressWarnings("unchecked")
public <T> BindableType<? super T> resolveParameterBindType(T bindValue) {
if ( bindValue == null ) {
// we can't guess
@ -57,7 +53,7 @@ public abstract class QueryParameterBindingTypeResolverImpl implements QueryPara
while ( c != Object.class );
if ( clazz.isEnum() ) {
return null;//createEnumType( (Class) clazz );
return null; //createEnumType( (Class) clazz );
}
else if ( Serializable.class.isAssignableFrom( clazz ) ) {
return (BindableType<? super T>) resolveParameterBindType( Serializable.class );
@ -67,16 +63,6 @@ public abstract class QueryParameterBindingTypeResolverImpl implements QueryPara
}
}
private <E extends Enum<E>> BasicType<E> createEnumType(Class<E> enumClass) {
final EnumJavaType<E> enumJavaType = new EnumJavaType<>( enumClass );
final JdbcType jdbcType =
// we don't know whether to map the enum as ORDINAL or STRING,
// so just accept the default from the TypeConfiguration, which
// is usually ORDINAL (the default according to JPA)
enumJavaType.getRecommendedJdbcType( getTypeConfiguration().getCurrentBaseSqlTypeIndicators() );
return new BasicTypeImpl<>( enumJavaType, jdbcType );
}
@SuppressWarnings("unchecked")
private static <T> Class<T> unproxiedClass(T bindValue) {
final LazyInitializer lazyInitializer = extractLazyInitializer( bindValue );

View File

@ -16,6 +16,7 @@ import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.metamodel.model.domain.internal.BasicTypeImpl;
import org.hibernate.query.BindableType;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection;
@ -27,7 +28,10 @@ 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;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -133,10 +137,27 @@ public abstract class AbstractJdbcParameter
final BindableType<?> parameterType =
executionContext.getSession().getFactory().getMappingMetamodel()
.resolveParameterBindType( bindValue );
return parameterType instanceof JdbcMapping ? (JdbcMapping) parameterType : null;
if ( parameterType == null && bindValue instanceof Enum ) {
return createEnumType( executionContext, (Class) bindValue.getClass() );
}
else {
return parameterType instanceof JdbcMapping ? (JdbcMapping) parameterType : null;
}
}
}
private static <E extends Enum<E>> BasicTypeImpl<E> createEnumType(ExecutionContext executionContext, Class<E> enumClass) {
final EnumJavaType<E> enumJavaType = new EnumJavaType<>( enumClass );
final JdbcTypeIndicators indicators =
executionContext.getSession().getTypeConfiguration().getCurrentBaseSqlTypeIndicators();
final JdbcType jdbcType =
// we don't know whether to map the enum as ORDINAL or STRING,
// so just accept the default from the TypeConfiguration, which
// is usually ORDINAL (the default according to JPA)
enumJavaType.getRecommendedJdbcType(indicators);
return new BasicTypeImpl<>( enumJavaType, jdbcType );
}
@Override
public MappingModelExpressible getExpressionType() {
return this;

View File

@ -2037,7 +2037,7 @@ public class FunctionTests {
session -> {
session.createSelectionQuery("from EntityOfBasics where gender is null").getResultList();
session.createSelectionQuery("from EntityOfBasics e where e.gender is null").getResultList();
// session.createSelectionQuery("from EntityOfBasics where :gender is null").setParameter("gender", EntityOfBasics.Gender.MALE).getResultList();
session.createSelectionQuery("from EntityOfBasics where :gender is null").setParameter("gender", EntityOfBasics.Gender.MALE).getResultList();
}
);
}