From 7ad39a86e9bef541e9d7bbcb5c439496363f0aed Mon Sep 17 00:00:00 2001 From: Gavin King Date: Fri, 1 Mar 2024 12:02:26 +0100 Subject: [PATCH] HHH-17772 allow array as return type for @Find methods as required by Jakarta Data --- .../annotation/AbstractQueryMethod.java | 11 ++++ .../annotation/AnnotationMetaEntity.java | 50 +++++++++++++++++-- .../annotation/CriteriaFinderMethod.java | 33 ++++++------ 3 files changed, 75 insertions(+), 19 deletions(-) diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AbstractQueryMethod.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AbstractQueryMethod.java index dfee2e7157..9321297830 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AbstractQueryMethod.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AbstractQueryMethod.java @@ -572,6 +572,17 @@ public abstract class AbstractQueryMethod implements MetaAttribute { } else { switch (containerType) { + case "[]": + if ( returnTypeName== null ) { + throw new AssertionFailure("missing return type"); + } + else { + declaration + .append(".getResultList()\n\t\t\t.toArray(new ") + .append(annotationMetaEntity.importType(returnTypeName)) + .append("[0]);"); + } + break; case OPTIONAL: declaration .append(".uniqueResultOptional();"); 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 77d3f0ea76..20a48df577 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 @@ -789,12 +789,34 @@ public class AnnotationMetaEntity extends AnnotationMeta { ExecutableElement method, @Nullable TypeMirror returnType, @Nullable TypeElement containerType) { - if ( returnType == null || returnType.getKind() != TypeKind.DECLARED ) { + if ( returnType == null ) { context.message( method, - "incorrect return type '" + returnType + "' is not an entity type", + "missing return type", Diagnostic.Kind.ERROR ); } - else { + else if ( returnType.getKind() == TypeKind.ARRAY ) { + final ArrayType arrayType = (ArrayType) returnType; + final TypeMirror componentType = arrayType.getComponentType(); + if ( componentType.getKind() != TypeKind.DECLARED ) { + context.message( method, + "incorrect return type '" + returnType + "' is not an array with entity elements", + Diagnostic.Kind.ERROR ); + } + else { + final DeclaredType declaredType = (DeclaredType) componentType; + final TypeElement entity = (TypeElement) declaredType.asElement(); + if ( !containsAnnotation( entity, Constants.ENTITY ) ) { + context.message( method, + "incorrect return type '" + returnType + "' is not annotated '@Entity'", + Diagnostic.Kind.ERROR ); + } + else { + // multiple results, it has to be a criteria finder + createCriteriaFinder( method, returnType, containerType, entity ); + } + } + } + else if ( returnType.getKind() == TypeKind.DECLARED ) { final DeclaredType declaredType = ununi( (DeclaredType) returnType ); final TypeElement entity = (TypeElement) declaredType.asElement(); if ( !containsAnnotation( entity, Constants.ENTITY ) ) { @@ -834,6 +856,11 @@ public class AnnotationMetaEntity extends AnnotationMeta { } } } + else { + context.message( method, + "incorrect return type '" + returnType + "' is not an entity type", + Diagnostic.Kind.ERROR ); + } } /** @@ -866,12 +893,25 @@ public class AnnotationMetaEntity extends AnnotationMeta { } } } + // TODO: this is ugly, do something better + // higher up in the call chain + final String containerTypeName; + final String entityTypeName; + if ( returnType.getKind() == TypeKind.ARRAY ) { + final ArrayType arrayType = (ArrayType) returnType; + entityTypeName = arrayType.getComponentType().toString(); + containerTypeName = "[]"; + } + else { + entityTypeName = returnType.toString(); + containerTypeName = containerType == null ? null : containerType.toString(); + } putMember( methodKey, new CriteriaFinderMethod( this, methodName, - returnType.toString(), - containerType == null ? null : containerType.toString(), + entityTypeName, + containerTypeName, paramNames, paramTypes, parameterNullability(method, entity), diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/CriteriaFinderMethod.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/CriteriaFinderMethod.java index 53aaa4571a..6c7dcfce01 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/CriteriaFinderMethod.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/CriteriaFinderMethod.java @@ -213,21 +213,26 @@ public class CriteriaFinderMethod extends AbstractFinderMethod { } private StringBuilder returnType() { - StringBuilder type = new StringBuilder(); - boolean returnsUni = isReactive() - && (containerType == null || LIST.equals(containerType)); - if ( returnsUni ) { - type.append(annotationMetaEntity.importType(Constants.UNI)).append('<'); + final StringBuilder type = new StringBuilder(); + if ( "[]".equals(containerType) ) { + type.append(returnTypeName).append("[]"); } - if ( containerType != null ) { - type.append(annotationMetaEntity.importType(containerType)).append('<'); - } - type.append(annotationMetaEntity.importType(entity)); - if ( containerType != null ) { - type.append('>'); - } - if ( returnsUni ) { - type.append('>'); + else { + boolean returnsUni = isReactive() + && (containerType == null || LIST.equals(containerType)); + if ( returnsUni ) { + type.append(annotationMetaEntity.importType(Constants.UNI)).append('<'); + } + if ( containerType != null ) { + type.append(annotationMetaEntity.importType(containerType)).append('<'); + } + type.append(annotationMetaEntity.importType(entity)); + if ( containerType != null ) { + type.append('>'); + } + if ( returnsUni ) { + type.append('>'); + } } return type; }