HHH-16633 support mutation query methods
This commit is contained in:
parent
4d005b3d19
commit
0918791f47
|
@ -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,45 +967,11 @@ 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();
|
||||
boolean returnTypeCorrect;
|
||||
if ( selection.isCompoundSelection() ) {
|
||||
switch ( returnType.getKind() ) {
|
||||
case ARRAY:
|
||||
returnTypeCorrect = checkReturnedArrayType((ArrayType) returnType);
|
||||
break;
|
||||
case DECLARED:
|
||||
if ( !checkConstructorReturn( (DeclaredType) returnType, selection ) ) {
|
||||
context.message(method, mirror, value,
|
||||
"return type '" + returnType
|
||||
+ "' of method has no constructor matching query selection list",
|
||||
Diagnostic.Kind.ERROR);
|
||||
}
|
||||
returnTypeCorrect = true;
|
||||
break;
|
||||
default:
|
||||
returnTypeCorrect = false;
|
||||
}
|
||||
}
|
||||
else if ( selection instanceof JpaEntityJoin ) {
|
||||
final JpaEntityJoin<?> from = (JpaEntityJoin<?>) selection;
|
||||
returnTypeCorrect = checkReturnedEntity( from.getModel(), returnType );
|
||||
}
|
||||
else if ( selection instanceof JpaRoot ) {
|
||||
final JpaRoot<?> from = (JpaRoot<?>) selection;
|
||||
returnTypeCorrect = checkReturnedEntity( from.getModel(), returnType );
|
||||
}
|
||||
else {
|
||||
// TODO: anything more we can do here? e.g. check constructor
|
||||
returnTypeCorrect = true;
|
||||
}
|
||||
if ( !returnTypeCorrect ) {
|
||||
context.message(method, mirror, value,
|
||||
"return type of query did not match return type '" + returnType + "' of method",
|
||||
Diagnostic.Kind.ERROR);
|
||||
}
|
||||
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);
|
||||
|
@ -1005,6 +979,67 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
break;
|
||||
case DECLARED:
|
||||
if ( !checkConstructorReturn( (DeclaredType) returnType, selection ) ) {
|
||||
context.message(method, mirror, value,
|
||||
"return type '" + returnType
|
||||
+ "' of method has no constructor matching query selection list",
|
||||
Diagnostic.Kind.ERROR);
|
||||
}
|
||||
returnTypeCorrect = true;
|
||||
break;
|
||||
default:
|
||||
returnTypeCorrect = false;
|
||||
}
|
||||
}
|
||||
else if ( selection instanceof JpaEntityJoin ) {
|
||||
final JpaEntityJoin<?> from = (JpaEntityJoin<?>) selection;
|
||||
returnTypeCorrect = checkReturnedEntity( from.getModel(), returnType );
|
||||
}
|
||||
else if ( selection instanceof JpaRoot ) {
|
||||
final JpaRoot<?> from = (JpaRoot<?>) selection;
|
||||
returnTypeCorrect = checkReturnedEntity( from.getModel(), returnType );
|
||||
}
|
||||
else {
|
||||
// TODO: anything more we can do here? e.g. check constructor
|
||||
returnTypeCorrect = true;
|
||||
}
|
||||
if ( !returnTypeCorrect ) {
|
||||
context.message(method, mirror, value,
|
||||
"return type of query did not match return type '" + returnType + "' of method",
|
||||
Diagnostic.Kind.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkConstructorReturn(DeclaredType returnType, JpaSelection<?> selection) {
|
||||
final List<? extends JpaSelection<?>> selectionItems = selection.getSelectionItems();
|
||||
if ( selectionItems == null ) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue