From 3b6d25425a8ae29244a4a29bb6c12d0afc28e512 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Tue, 8 Feb 2022 14:14:22 +0100 Subject: [PATCH] HHH-15073 Test criteria query built from JPA metamodel and involving primitive types --- .../query/spi/AbstractSelectionQuery.java | 29 ++++++++++++++----- .../criteria/CriteriaPrimitiveIdTest.java | 2 ++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java index 5bd78e0d51..b8cb2d279d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java @@ -65,6 +65,8 @@ import org.hibernate.sql.exec.internal.CallbackImpl; import org.hibernate.sql.exec.spi.Callback; import org.hibernate.sql.results.internal.TupleMetadata; import org.hibernate.type.BasicType; +import org.hibernate.type.descriptor.java.JavaType; +import org.hibernate.type.descriptor.java.spi.PrimitiveJavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; import static org.hibernate.cfg.AvailableSettings.JAKARTA_SHARED_CACHE_RETRIEVE_MODE; @@ -279,9 +281,16 @@ public abstract class AbstractSelectionQuery SqmExpressible sqmExpressible, SessionFactoryImplementor sessionFactory) { assert sqmExpressible != null; - assert sqmExpressible.getExpressibleJavaType() != null; - final Class javaTypeClass = sqmExpressible.getExpressibleJavaType().getJavaTypeClass(); + final JavaType expressibleJavaType = sqmExpressible.getExpressibleJavaType(); + assert expressibleJavaType != null; + final Class javaTypeClass = expressibleJavaType.getJavaTypeClass(); if ( !resultClass.isAssignableFrom( javaTypeClass ) ) { + if ( expressibleJavaType instanceof PrimitiveJavaType ) { + if ( ( (PrimitiveJavaType) expressibleJavaType ).getPrimitiveClass() == resultClass ) { + return; + } + throwQueryTypeMismatchException( resultClass, sqmExpressible ); + } // Special case for date because we always report java.util.Date as expression type // But the expected resultClass could be a subtype of that, so we need to check the JdbcType if ( javaTypeClass == Date.class ) { @@ -315,15 +324,19 @@ public abstract class AbstractSelectionQuery } } } - final String errorMessage = String.format( - "Specified result type [%s] did not match Query selection type [%s] - multiple selections: use Tuple or array", - resultClass.getName(), - sqmExpressible.getExpressibleJavaType().getJavaType().getTypeName() - ); - throw new QueryTypeMismatchException( errorMessage ); + throwQueryTypeMismatchException( resultClass, sqmExpressible ); } } + private static void throwQueryTypeMismatchException(Class resultClass, SqmExpressible sqmExpressible) { + final String errorMessage = String.format( + "Specified result type [%s] did not match Query selection type [%s] - multiple selections: use Tuple or array", + resultClass.getName(), + sqmExpressible.getExpressibleJavaType().getJavaType().getTypeName() + ); + throw new QueryTypeMismatchException( errorMessage ); + } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // execution diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaPrimitiveIdTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaPrimitiveIdTest.java index b23e608b87..798a5dcf8a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaPrimitiveIdTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaPrimitiveIdTest.java @@ -62,6 +62,8 @@ public class CriteriaPrimitiveIdTest extends BaseCoreFunctionalTestCase { @Id private long id; + private String name; + public MyEntity() { }