HHH-16633 support mutation query methods

This commit is contained in:
Gavin King 2023-07-16 17:42:16 +02:00
parent 4d005b3d19
commit 0918791f47
2 changed files with 95 additions and 45 deletions

View File

@ -417,7 +417,11 @@ public class AnnotationMetaEntity extends AnnotationMeta {
private void addQueryMethod(ExecutableElement method) {
final TypeMirror returnType = method.getReturnType();
if ( returnType.getKind() == TypeKind.DECLARED ) {
final TypeKind kind = returnType.getKind();
if ( kind == TypeKind.VOID || kind.isPrimitive() ) {
addQueryMethod( method, returnType, null );
}
else if ( kind == TypeKind.DECLARED ) {
final DeclaredType declaredType = ununi((DeclaredType) returnType);
final TypeElement typeElement = (TypeElement) declaredType.asElement();
final List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
@ -925,6 +929,10 @@ public class AnnotationMetaEntity extends AnnotationMeta {
containerType == null ? null : containerType.getQualifiedName().toString(),
paramNames,
paramTypes,
// update/delete/insert query methods must return int or void
returnType != null
&& returnType.getKind() != TypeKind.DECLARED
&& returnType.getKind() != TypeKind.ARRAY,
isNative,
dao,
sessionType[0],
@ -959,14 +967,45 @@ public class AnnotationMetaEntity extends AnnotationMeta {
ProcessorSessionFactory.create( context.getProcessingEnvironment() )
);
if ( statement != null ) {
if ( statement instanceof SqmSelectStatement && returnType != null ) {
final SqmSelectStatement<?> select = (SqmSelectStatement<?>) statement;
final JpaSelection<?> selection = select.getSelection();
if ( statement instanceof SqmSelectStatement ) {
validateSelectHql( method, returnType, mirror, value, (SqmSelectStatement<?>) statement );
}
else {
validateUpdateHql( method, returnType, mirror, value );
}
for ( SqmParameter<?> param : statement.getSqmParameters() ) {
checkParameter( param, paramNames, paramTypes, method, mirror, value);
}
}
}
private void validateUpdateHql(
ExecutableElement method,
@Nullable TypeMirror returnType,
AnnotationMirror mirror,
AnnotationValue value) {
if ( returnType == null
|| returnType.getKind() != TypeKind.VOID
&& returnType.getKind() != TypeKind.INT ) {
context.message( method, mirror, value,
"return type of mutation query method must be 'int' or 'void'",
Diagnostic.Kind.ERROR );
}
}
private void validateSelectHql(
ExecutableElement method,
@Nullable TypeMirror returnType,
AnnotationMirror mirror,
AnnotationValue value,
SqmSelectStatement<?> statement) {
if ( returnType != null ) {
final JpaSelection<?> selection = statement.getSelection();
boolean returnTypeCorrect;
if ( selection.isCompoundSelection() ) {
switch ( returnType.getKind() ) {
case ARRAY:
returnTypeCorrect = checkReturnedArrayType((ArrayType) returnType);
returnTypeCorrect = checkReturnedArrayType( (ArrayType) returnType );
break;
case DECLARED:
if ( !checkConstructorReturn( (DeclaredType) returnType, selection ) ) {
@ -999,10 +1038,6 @@ public class AnnotationMetaEntity extends AnnotationMeta {
Diagnostic.Kind.ERROR);
}
}
for ( SqmParameter<?> param : statement.getSqmParameters() ) {
checkParameter( param, paramNames, paramTypes, method, mirror, value);
}
}
}
private static boolean checkConstructorReturn(DeclaredType returnType, JpaSelection<?> selection) {

View File

@ -24,6 +24,7 @@ public class QueryMethod extends AbstractQueryMethod {
private final String queryString;
private final @Nullable String returnTypeName;
private final @Nullable String containerTypeName;
private final boolean isUpdate;
private final boolean isNative;
public QueryMethod(
@ -36,6 +37,7 @@ public class QueryMethod extends AbstractQueryMethod {
String containerTypeName,
List<String> paramNames,
List<String> paramTypes,
boolean isUpdate,
boolean isNative,
boolean belongsToDao,
String sessionType,
@ -49,6 +51,7 @@ public class QueryMethod extends AbstractQueryMethod {
this.queryString = queryString;
this.returnTypeName = returnTypeName;
this.containerTypeName = containerTypeName;
this.isUpdate = isUpdate;
this.isNative = isNative;
}
@ -81,7 +84,11 @@ public class QueryMethod extends AbstractQueryMethod {
parameters( paramTypes, declaration );
declaration
.append(" {")
.append("\n\treturn ");
.append("\n\t");
if ( returnTypeName == null || !returnTypeName.equals("void") ) {
declaration
.append("return ");
}
if ( isNative && returnTypeName != null && containerTypeName == null
&& isUsingEntityManager() ) {
// EntityManager.createNativeQuery() does not return TypedQuery,
@ -95,7 +102,7 @@ public class QueryMethod extends AbstractQueryMethod {
.append(isNative ? ".createNativeQuery" : ".createQuery")
.append("(")
.append(getConstantName());
if ( returnTypeName != null ) {
if ( returnTypeName != null && !isUpdate ) {
declaration
.append(", ")
.append(annotationMetaEntity.importType(returnTypeName))
@ -103,7 +110,17 @@ public class QueryMethod extends AbstractQueryMethod {
}
declaration.append(")");
boolean unwrapped = setParameters( paramTypes, declaration );
if ( containerTypeName == null) {
execute( declaration, unwrapped );
declaration.append(";\n}");
return declaration.toString();
}
private void execute(StringBuilder declaration, boolean unwrapped) {
if ( isUpdate ) {
declaration
.append("\n\t\t\t.executeUpdate()");
}
else if ( containerTypeName == null) {
declaration
.append("\n\t\t\t.getSingleResult()");
}
@ -122,8 +139,6 @@ public class QueryMethod extends AbstractQueryMethod {
}
}
declaration.append(";\n}");
return declaration.toString();
}
private boolean setParameters(List<String> paramTypes, StringBuilder declaration) {