Unify parameter type resolving

This commit is contained in:
Christian Beikov 2021-11-12 17:33:55 +01:00 committed by Karel Maesen
parent f967e16fee
commit 3e97b1c205
7 changed files with 39 additions and 75 deletions

View File

@ -437,12 +437,12 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor,
}
@Override
public AllowableParameterType<?> resolveParameterBindType(Object bindValue) {
public <T> AllowableParameterType<T> resolveParameterBindType(T bindValue) {
return delegate.resolveParameterBindType( bindValue );
}
@Override
public AllowableParameterType<?> resolveParameterBindType(Class<?> clazz) {
public <T> AllowableParameterType<T> resolveParameterBindType(Class<T> clazz) {
return delegate.resolveParameterBindType( clazz );
}

View File

@ -1081,7 +1081,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
}
@Override
public AllowableParameterType<?> resolveParameterBindType(Object bindValue) {
public <T> AllowableParameterType<T> resolveParameterBindType(T bindValue) {
if ( bindValue == null ) {
// we can't guess
return null;
@ -1091,7 +1091,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
}
@Override
public AllowableParameterType<?> resolveParameterBindType(Class<?> javaType) {
public <T> AllowableParameterType<T> resolveParameterBindType(Class<T> javaType) {
return getMetamodel().resolveQueryParameterType( javaType );
}

View File

@ -71,6 +71,8 @@ import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.type.BasicType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting.determineJpaMetaModelPopulationSetting;
@ -834,17 +836,28 @@ public class MappingMetamodelImpl implements MappingMetamodel, MetamodelImplemen
}
@Override
public <T> AllowableParameterType<T> resolveQueryParameterType(Class<T> javaType) {
final BasicType basicType = getTypeConfiguration().getBasicTypeForJavaType( javaType );
if ( basicType != null ) {
//noinspection unchecked
public <T> AllowableParameterType<T> resolveQueryParameterType(Class<T> javaClass) {
final BasicType<T> basicType = getTypeConfiguration().getBasicTypeForJavaType( javaClass );
// For enums, we simply don't know the exact mapping if there is no basic type registered
if ( basicType != null || javaClass.isEnum() ) {
return basicType;
}
final ManagedDomainType<T> managedType = jpaMetamodel.findManagedType( javaType );
if ( managedType instanceof AllowableParameterType ) {
//noinspection unchecked
return (AllowableParameterType) managedType;
final ManagedDomainType<T> managedType = jpaMetamodel.findManagedType( javaClass );
if ( managedType != null ) {
return managedType;
}
final JavaType<T> javaType = getTypeConfiguration().getJavaTypeDescriptorRegistry()
.findDescriptor( javaClass );
if ( javaType != null ) {
final JdbcType recommendedJdbcType = javaType.getRecommendedJdbcType( getTypeConfiguration().getCurrentBaseSqlTypeIndicators() );
if ( recommendedJdbcType != null ) {
return getTypeConfiguration().getBasicTypeRegistry().resolve(
javaType,
recommendedJdbcType
);
}
}
return null;

View File

@ -19,14 +19,15 @@ public final class HibernateProxyHelper {
* of a proxy (without initializing the proxy!). It is
* almost always better to use the entity name!
*/
public static Class getClassWithoutInitializingProxy(Object object) {
@SuppressWarnings("unchecked")
public static <T> Class<T> getClassWithoutInitializingProxy(T object) {
if (object instanceof HibernateProxy) {
HibernateProxy proxy = (HibernateProxy) object;
LazyInitializer li = proxy.getHibernateLazyInitializer();
return li.getPersistentClass();
}
else {
return object.getClass();
return (Class<T>) object.getClass();
}
}

View File

@ -16,7 +16,7 @@ import org.hibernate.type.spi.TypeConfiguration;
* @author Steve Ebersole
*/
public interface QueryParameterBindingTypeResolver {
AllowableParameterType<?> resolveParameterBindType(Object bindValue);
AllowableParameterType<?> resolveParameterBindType(Class<?> clazz);
<T> AllowableParameterType<T> resolveParameterBindType(T bindValue);
<T> AllowableParameterType<T> resolveParameterBindType(Class<T> clazz);
TypeConfiguration getTypeConfiguration();
}

View File

@ -900,10 +900,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return new SqmLiteralNull<>( this );
}
//noinspection unchecked
return new SqmLiteral<>(
value,
getTypeConfiguration().standardBasicTypeForJavaType( (Class<T>) value.getClass() ),
queryEngine.getTypeConfiguration().getSessionFactory().resolveParameterBindType( value ),
this
);
}
@ -1444,41 +1443,14 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return literal( value );
}
else {
final BasicType<T> basicType;
if ( value == null ) {
basicType = null;
}
else {
//noinspection unchecked
basicType = guessType( value );
}
return new JpaCriteriaParameter<>(
basicType,
queryEngine.getTypeConfiguration().getSessionFactory().resolveParameterBindType( value ),
value,
this
);
}
}
@SuppressWarnings("unchecked")
private <T> BasicType<T> guessType(T value) {
BasicType<T> basicType;
Class<T> valueClass = (Class<T>) value.getClass();
basicType = getTypeConfiguration().getBasicTypeForJavaType( valueClass );
if ( basicType == null ) {
final JavaType<Object> javaType = getTypeConfiguration().getJavaTypeDescriptorRegistry()
.findDescriptor( valueClass );
if ( javaType != null ) {
final JdbcType recommendedJdbcType = javaType.getRecommendedJdbcType( getTypeConfiguration().getCurrentBaseSqlTypeIndicators() );
if ( recommendedJdbcType != null ) {
basicType = (BasicType<T>) getTypeConfiguration().getBasicTypeRegistry().resolve( javaType, recommendedJdbcType);
}
}
}
assert basicType != null;
return basicType;
}
@Override
public <V, C extends Collection<V>> SqmExpression<Collection<V>> values(C collection) {
throw new NotYetImplementedFor6Exception();

View File

@ -15,6 +15,7 @@ import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.metamodel.mapping.SqlExpressable;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
@ -102,38 +103,15 @@ public abstract class AbstractJdbcParameter
}
private JdbcMapping guessBindType(ExecutionContext executionContext, JdbcParameterBinding binding, JdbcMapping jdbcMapping) {
final Class<?> valueClass;
if ( binding.getBindValue() == null ) {
if ( jdbcMapping != null ) {
return jdbcMapping;
}
valueClass = Object.class;
}
else {
valueClass = binding.getBindValue().getClass();
if ( binding.getBindValue() == null && jdbcMapping != null ) {
return jdbcMapping;
}
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final TypeConfiguration typeConfiguration = factory.getTypeConfiguration();
final BasicType<?> basicType = typeConfiguration.getBasicTypeRegistry().getRegisteredType( valueClass );
if ( basicType != null ) {
return basicType.getJdbcMapping();
final AllowableParameterType<?> parameterType = executionContext.getSession().getFactory()
.resolveParameterBindType( binding.getBindValue() );
if ( parameterType instanceof JdbcMapping ) {
return (JdbcMapping) parameterType;
}
final BasicType<?> defaultForJavaType = typeConfiguration.getBasicTypeForJavaType( valueClass );
if ( defaultForJavaType != null ) {
return defaultForJavaType;
}
final JavaType<Object> javaType = typeConfiguration.getJavaTypeDescriptorRegistry().findDescriptor( valueClass );
if ( javaType != null ) {
final JdbcType recommendedJdbcType = javaType.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() );
if ( recommendedJdbcType != null ) {
return typeConfiguration.getBasicTypeRegistry().resolve( javaType, recommendedJdbcType );
}
}
return null;
}