diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java index b2453cb9b7..d64eb73eb8 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java @@ -64,6 +64,8 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParametersList; import org.hibernate.type.JavaObjectType; import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; +import org.hibernate.type.internal.BasicTypeImpl; +import org.hibernate.type.internal.ConvertedBasicTypeImpl; import org.hibernate.type.spi.TypeConfiguration; import static org.hibernate.query.sqm.tree.jpa.ParameterCollector.collectParameters; @@ -439,12 +441,19 @@ public class SqmUtil { List> sqmParameters, SqmParameterMappingModelResolutionAccess mappingModelResolutionAccess, SessionFactoryImplementor sessionFactory) { - if ( binding.getBindType() instanceof Bindable ) { - return (Bindable) binding.getBindType(); + + { + final Bindable tryOne = asBindable( binding.getBindType() ); + if ( tryOne != null ) { + return tryOne; + } } - if ( parameter.getHibernateType() instanceof Bindable ) { - return (Bindable) parameter.getHibernateType(); + { + final Bindable tryTwo = asBindable( parameter.getHibernateType() ); + if ( tryTwo != null ) { + return tryTwo; + } } if ( binding.getType() != null ) { @@ -465,6 +474,35 @@ public class SqmUtil { return typeConfiguration.standardBasicTypeForJavaType( parameter.getParameterType() ); } + /** + * Utility to mitigate issues related to type pollution. + * Returns the passes object after casting it to Bindable, + * if the type is compatible. + * If it's not, null will be returned. + * @param o any object instance + * @return a reference to the same object o, but of type Bindable if possible, or null. + */ + private static Bindable asBindable(final Object o) { + if ( o == null ) { + return null; + } + //There's a high chance that we're dealing with a BasicTypeImpl, or a subclass of it. + else if ( o instanceof BasicTypeImpl ) { + return (BasicTypeImpl) o; + } + //Alternatively, chances are good that we're dealing with an ConvertedBasicTypeImpl. + else if ( o instanceof ConvertedBasicTypeImpl ) { + return (ConvertedBasicTypeImpl) o; + } + else { + //Eventually fallback to the standard check for completeness: + if ( o instanceof Bindable ) { + return (Bindable) o; + } + return null; + } + } + public static SqmStatement.ParameterResolutions resolveParameters(SqmStatement statement) { if ( statement.getQuerySource() == SqmQuerySource.CRITERIA ) { final CriteriaParameterCollector parameterCollector = new CriteriaParameterCollector();