From e5a994bfa130502fddc76853f7f048d2bd9e74a9 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Sun, 11 Feb 2024 18:46:56 +0100 Subject: [PATCH] fix typechecking of primitives in instantiations for query methods --- .../hql/internal/SemanticQueryBuilder.java | 2 +- .../sqm/tree/expression/Compatibility.java | 2 +- ...icInstantiationAssemblerInjectionImpl.java | 2 +- .../internal/InstantiationHelper.java | 6 ++-- .../annotation/AnnotationMetaEntity.java | 31 +++++++++++++++++-- .../jpamodelgen/test/hqlsql/Dao.java | 3 ++ 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java index dc77428c56..c94de47422 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java @@ -1495,7 +1495,7 @@ public SqmDynamicInstantiationArgument visitInstantiationArgument(HqlParser.I final HqlParser.VariableContext variable = ctx.variable(); final String alias = variable == null ? null : extractAlias( variable ); - final SqmSelectableNode argExpression = + final SqmSelectableNode argExpression = (SqmSelectableNode) ctx.instantiationArgumentExpression().accept( this ); final SqmDynamicInstantiationArgument argument = new SqmDynamicInstantiationArgument<>( diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/Compatibility.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/Compatibility.java index 3413e2483c..689a3841fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/Compatibility.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/Compatibility.java @@ -164,6 +164,6 @@ private static boolean isCompatibleFloatingTypePrimitive(Class to, Class f assert isFloatingTypePrimitive( to ); assert from.isPrimitive(); - return to == float.class ? from == float.class : isFloatingTypePrimitive( from ); + return to == float.class ? from == float.class : isFloatingTypePrimitive( from ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/DynamicInstantiationAssemblerInjectionImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/DynamicInstantiationAssemblerInjectionImpl.java index 835a03d121..19ee0ca57a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/DynamicInstantiationAssemblerInjectionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/DynamicInstantiationAssemblerInjectionImpl.java @@ -92,7 +92,7 @@ public T assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcess result = constructor.newInstance(); } catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException - | java.lang.InstantiationException e ) { + | java.lang.InstantiationException e ) { throw new InstantiationException( "Error instantiating class '" + target.getJavaType().getTypeName() + "' using default constructor: " + e.getMessage(), e ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/InstantiationHelper.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/InstantiationHelper.java index be219c353e..ce6c20e6cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/InstantiationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/InstantiationHelper.java @@ -35,8 +35,8 @@ public static boolean isInjectionCompatible(Class targetJavaType, List { - for ( int i = 0; i < aliases.size(); i++ ) { - final String alias = aliases.get(i); + for ( int i = 0; i < aliases.size(); i++ ) { + final String alias = aliases.get(i); final Class argType = argTypes.get(i); if ( !checkArgument( targetJavaType, beanInfo, alias, argType ) ) { return false; @@ -78,7 +78,7 @@ public static boolean isConstructorCompatible( ? (Class) parameterType : typeConfiguration.getJavaTypeRegistry().resolveDescriptor( parameterType ).getJavaTypeClass(); - if ( !areAssignmentCompatible( type, argumentType ) ) { + if ( !areAssignmentCompatible( type, argumentType ) ) { if ( log.isDebugEnabled() ) { log.debugf( "Skipping constructor for dynamic-instantiation match due to argument mismatch [%s] : %s -> %s", diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java index 61b9dd4f8a..a7c862f075 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java @@ -1260,8 +1260,10 @@ private static boolean constructorMatches( } private static boolean parameterMatches(VariableElement parameter, JpaSelection item) { - final Class itemType = item.getJavaType(); - final TypeMirror parameterType = parameter.asType(); + return parameterMatches( parameter.asType(), item.getJavaType() ); + } + + private static boolean parameterMatches(TypeMirror parameterType, Class itemType) { final TypeKind kind = parameterType.getKind(); final String itemTypeName = itemType.getName(); if ( kind == TypeKind.DECLARED ) { @@ -1270,7 +1272,30 @@ private static boolean parameterMatches(VariableElement parameter, JpaSelection< return paramTypeElement.getQualifiedName().contentEquals(itemTypeName); } else if ( kind.isPrimitive() ) { - return parameterType.toString().equals(itemTypeName); + switch ( kind ) { + case SHORT: + return itemType.equals(Short.class); + case INT: + return itemType.equals(Integer.class); + case LONG: + return itemType.equals(Long.class); + case BOOLEAN: + return itemType.equals(Boolean.class); + case FLOAT: + return itemType.equals(Float.class); + case DOUBLE: + return itemType.equals(Double.class); + case CHAR: + return itemType.equals(Character.class); + case BYTE: + return itemType.equals(Byte.class); + default: + return false; + } + } + else if ( kind == TypeKind.ARRAY ) { + return itemType.isArray() + && parameterMatches( ((ArrayType) parameterType).getComponentType(), itemType.getComponentType() ); } else { return false; diff --git a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/hqlsql/Dao.java b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/hqlsql/Dao.java index e6d4771c20..7a7c927955 100644 --- a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/hqlsql/Dao.java +++ b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/hqlsql/Dao.java @@ -51,4 +51,7 @@ public interface Dao { @HQL("select new org.hibernate.jpamodelgen.test.hqlsql.Dto(title, pages) from Book") List dtoQuery(); + @HQL("select title, pages from Book") + List dtoQuery2(); + }