validate the type arg of Order parameters in @Find and @HQL methods
This commit is contained in:
parent
508df48686
commit
cb1b276ff8
|
@ -26,6 +26,7 @@ import javax.lang.model.type.DeclaredType;
|
||||||
import javax.lang.model.type.ExecutableType;
|
import javax.lang.model.type.ExecutableType;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
import javax.lang.model.type.WildcardType;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
@ -41,6 +42,7 @@ import org.hibernate.jpamodelgen.util.Constants;
|
||||||
import org.hibernate.jpamodelgen.validation.ProcessorSessionFactory;
|
import org.hibernate.jpamodelgen.validation.ProcessorSessionFactory;
|
||||||
import org.hibernate.jpamodelgen.validation.Validation;
|
import org.hibernate.jpamodelgen.validation.Validation;
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
|
import org.hibernate.query.Order;
|
||||||
import org.hibernate.query.criteria.JpaEntityJoin;
|
import org.hibernate.query.criteria.JpaEntityJoin;
|
||||||
import org.hibernate.query.criteria.JpaRoot;
|
import org.hibernate.query.criteria.JpaRoot;
|
||||||
import org.hibernate.query.criteria.JpaSelection;
|
import org.hibernate.query.criteria.JpaSelection;
|
||||||
|
@ -592,9 +594,23 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
final List<String> paramTypes = parameterTypes( method );
|
final List<String> paramTypes = parameterTypes( method );
|
||||||
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
||||||
final String methodKey = methodName + paramTypes;
|
final String methodKey = methodName + paramTypes;
|
||||||
for ( VariableElement param : method.getParameters() ) {
|
for ( VariableElement parameter : method.getParameters() ) {
|
||||||
if ( isFinderParameterMappingToAttribute( param ) ) {
|
if ( isFinderParameterMappingToAttribute( parameter ) ) {
|
||||||
validateFinderParameter( entity, param );
|
validateFinderParameter( entity, parameter );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final TypeMirror parameterType = parameter.asType();
|
||||||
|
if ( isOrderParam( parameterType.toString() ) ) {
|
||||||
|
final TypeMirror typeArgument = getTypeArgument( parameterType );
|
||||||
|
if ( typeArgument == null ) {
|
||||||
|
context.message( parameter, "missing type of order (should be 'Order<? super "
|
||||||
|
+ entity.getSimpleName() + ">')", Diagnostic.Kind.ERROR );
|
||||||
|
}
|
||||||
|
else if ( !context.getTypeUtils().isSameType( typeArgument, entity.asType() ) ) {
|
||||||
|
context.message( parameter, "mismatched type of order (should be 'Order<? super "
|
||||||
|
+ entity.getSimpleName() + ">')", Diagnostic.Kind.ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
putMember( methodKey,
|
putMember( methodKey,
|
||||||
|
@ -615,6 +631,38 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static @Nullable TypeMirror getTypeArgument(TypeMirror parameterType) {
|
||||||
|
switch ( parameterType.getKind() ) {
|
||||||
|
case ARRAY:
|
||||||
|
final ArrayType arrayType = (ArrayType) parameterType;
|
||||||
|
return getTypeArgument( arrayType.getComponentType() );
|
||||||
|
case DECLARED:
|
||||||
|
final DeclaredType type = (DeclaredType) parameterType;
|
||||||
|
if ( parameterType.toString().startsWith( List.class.getName() ) ) {
|
||||||
|
for (TypeMirror arg : type.getTypeArguments()) {
|
||||||
|
return getTypeArgument( arg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( parameterType.toString().startsWith( Order.class.getName() ) ) {
|
||||||
|
for ( TypeMirror arg : type.getTypeArguments() ) {
|
||||||
|
switch ( arg.getKind() ) {
|
||||||
|
case WILDCARD:
|
||||||
|
return ((WildcardType) arg).getSuperBound();
|
||||||
|
case ARRAY:
|
||||||
|
case DECLARED:
|
||||||
|
case TYPEVAR:
|
||||||
|
return arg;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isFinderParameterMappingToAttribute(VariableElement param) {
|
private static boolean isFinderParameterMappingToAttribute(VariableElement param) {
|
||||||
final String type = param.asType().toString();
|
final String type = param.asType().toString();
|
||||||
return !isSessionParameter( type )
|
return !isSessionParameter( type )
|
||||||
|
@ -1006,7 +1054,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check that the query has a parameter for every method parameter
|
// now check that the query has a parameter for every method parameter
|
||||||
checkParameters( method, paramNames, paramTypes, mirror, value, queryString );
|
checkParameters( method, returnType, paramNames, paramTypes, mirror, value, queryString );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1375,6 +1423,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
|
|
||||||
private void checkParameters(
|
private void checkParameters(
|
||||||
ExecutableElement method,
|
ExecutableElement method,
|
||||||
|
@Nullable TypeMirror returnType,
|
||||||
List<String> paramNames, List<String> paramTypes,
|
List<String> paramNames, List<String> paramTypes,
|
||||||
AnnotationMirror mirror,
|
AnnotationMirror mirror,
|
||||||
AnnotationValue value,
|
AnnotationValue value,
|
||||||
|
@ -1389,6 +1438,22 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
Diagnostic.Kind.ERROR );
|
Diagnostic.Kind.ERROR );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( returnType != null ) {
|
||||||
|
for ( VariableElement parameter : method.getParameters() ) {
|
||||||
|
final TypeMirror parameterType = parameter.asType();
|
||||||
|
final TypeMirror typeArgument = getTypeArgument( parameterType );
|
||||||
|
if ( isOrderParam( parameterType.toString() ) ) {
|
||||||
|
if ( typeArgument == null ) {
|
||||||
|
context.message( parameter, "missing type of order (should be 'Order<? super "
|
||||||
|
+ returnType + ">')", Diagnostic.Kind.ERROR );
|
||||||
|
}
|
||||||
|
else if ( !context.getTypeUtils().isSameType(typeArgument, returnType) ) {
|
||||||
|
context.message( parameter, "mismatched type of order (should be 'Order<? super "
|
||||||
|
+ returnType + ">')", Diagnostic.Kind.ERROR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean parameterIsMissing(String hql, int i, String param, String type) {
|
private static boolean parameterIsMissing(String hql, int i, String param, String type) {
|
||||||
|
|
|
@ -32,5 +32,5 @@ public abstract class Books {
|
||||||
static class Summary { Summary(String title, String publisher, String isbn) {} }
|
static class Summary { Summary(String title, String publisher, String isbn) {} }
|
||||||
|
|
||||||
@HQL("select title, publisher.name, isbn from Book")
|
@HQL("select title, publisher.name, isbn from Book")
|
||||||
abstract List<Summary> summarize(Session session, Order order);
|
abstract List<Summary> summarize(Session session, Order<Summary> order);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue