HHH-17772 support Jakarta Data @OrderBy
This commit is contained in:
parent
aed8244dae
commit
4cfc3fb97d
|
@ -36,6 +36,7 @@ import org.hibernate.AssertionFailure;
|
|||
import org.hibernate.jpamodelgen.Context;
|
||||
import org.hibernate.jpamodelgen.ImportContextImpl;
|
||||
import org.hibernate.jpamodelgen.ProcessLaterException;
|
||||
import org.hibernate.jpamodelgen.annotation.CriteriaFinderMethod.OrderBy;
|
||||
import org.hibernate.jpamodelgen.model.ImportContext;
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
|
@ -733,11 +734,48 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
sessionType[0],
|
||||
sessionType[1],
|
||||
enabledFetchProfiles( method ),
|
||||
orderByList( method, entity ),
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private List<OrderBy> orderByList(ExecutableElement method, TypeElement entityType) {
|
||||
final AnnotationMirror orderByList =
|
||||
getAnnotationMirror( method, "jakarta.data.repository.OrderBy.List" );
|
||||
if ( orderByList != null ) {
|
||||
final List<OrderBy> result = new ArrayList<>();
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<AnnotationValue> list = (List<AnnotationValue>)
|
||||
castNonNull( getAnnotationValue( orderByList, "value" ) );
|
||||
for ( AnnotationValue element : list ) {
|
||||
result.add( orderByExpression( castNonNull( (AnnotationMirror) element.getValue() ), entityType, method ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
final AnnotationMirror orderBy =
|
||||
getAnnotationMirror( method, "jakarta.data.repository.OrderBy" );
|
||||
if ( orderBy != null ) {
|
||||
return List.of( orderByExpression(orderBy, entityType, method) );
|
||||
}
|
||||
return emptyList();
|
||||
}
|
||||
|
||||
private OrderBy orderByExpression(AnnotationMirror orderBy, TypeElement entityType, ExecutableElement method) {
|
||||
final String fieldName = (String) castNonNull( getAnnotationValue(orderBy, "value") );
|
||||
final Boolean descendingOrNull = (Boolean) getAnnotationValue(orderBy, "descending");
|
||||
final Boolean ignoreCaseOrNull = (Boolean) getAnnotationValue(orderBy, "ignoreCase");
|
||||
final boolean descending = descendingOrNull != null && descendingOrNull;
|
||||
final boolean ignoreCase = ignoreCaseOrNull != null && ignoreCaseOrNull;
|
||||
if ( memberMatchingPath( entityType, fieldName ) == null ) {
|
||||
context.message( method, orderBy,
|
||||
"no matching field named '" + fieldName
|
||||
+ "' in entity class '" + entityType.getQualifiedName() + "'",
|
||||
Diagnostic.Kind.ERROR );
|
||||
}
|
||||
return new OrderBy( fieldName, descending, ignoreCase );
|
||||
}
|
||||
|
||||
private static @Nullable TypeMirror getTypeArgument(TypeMirror parameterType) {
|
||||
switch ( parameterType.getKind() ) {
|
||||
case ARRAY:
|
||||
|
@ -865,6 +903,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
sessionType[0],
|
||||
sessionType[1],
|
||||
enabledFetchProfiles( method ),
|
||||
orderByList( method, entity ),
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
);
|
||||
|
@ -932,6 +971,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
sessionType[0],
|
||||
sessionType[1],
|
||||
profiles,
|
||||
orderByList( method, entity ),
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
);
|
||||
|
@ -988,7 +1028,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
}
|
||||
|
||||
private @Nullable FieldType validateFinderParameter(TypeElement entityType, VariableElement param) {
|
||||
final Element member = memberMatchingParameter(entityType, param);
|
||||
final Element member = memberMatchingPath( entityType, parameterName( param ) );
|
||||
if ( member != null) {
|
||||
final String memberType = memberType( member ).toString();
|
||||
final String paramType = param.asType().toString();
|
||||
|
@ -1027,7 +1067,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
}
|
||||
|
||||
private boolean finderParameterNullable(TypeElement entity, VariableElement param) {
|
||||
final Element member = memberMatchingParameter(entity, param);
|
||||
final Element member = memberMatchingPath( entity, parameterName( param ) );
|
||||
return member == null || isNullable(member);
|
||||
}
|
||||
|
||||
|
@ -1047,17 +1087,17 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
}
|
||||
}
|
||||
|
||||
private @Nullable Element memberMatchingParameter(TypeElement entityType, VariableElement param) {
|
||||
final StringTokenizer tokens = new StringTokenizer( parameterName( param ), "$" );
|
||||
return memberMatchingParameter( entityType, param, tokens );
|
||||
private @Nullable Element memberMatchingPath(TypeElement entityType, String path) {
|
||||
final StringTokenizer tokens = new StringTokenizer( path, "$" );
|
||||
return memberMatchingPath( entityType, tokens );
|
||||
}
|
||||
|
||||
private @Nullable Element memberMatchingParameter(TypeElement entityType, VariableElement param, StringTokenizer tokens) {
|
||||
private @Nullable Element memberMatchingPath(TypeElement entityType, StringTokenizer tokens) {
|
||||
final AccessType accessType = getAccessType(entityType);
|
||||
final String nextToken = tokens.nextToken();
|
||||
for ( Element member : entityType.getEnclosedElements() ) {
|
||||
final Element match =
|
||||
memberMatchingParameter(entityType, param, member, accessType, tokens, nextToken);
|
||||
memberMatchingPath(entityType, member, accessType, tokens, nextToken);
|
||||
if ( match != null ) {
|
||||
return match;
|
||||
}
|
||||
|
@ -1065,9 +1105,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
return null;
|
||||
}
|
||||
|
||||
private @Nullable Element memberMatchingParameter(
|
||||
private @Nullable Element memberMatchingPath(
|
||||
TypeElement entityType,
|
||||
VariableElement param,
|
||||
Element candidate,
|
||||
AccessType accessType,
|
||||
StringTokenizer tokens,
|
||||
|
@ -1101,7 +1140,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
final TypeElement memberType = (TypeElement) declaredType.asElement();
|
||||
memberTypes.put( qualify( entityType.getQualifiedName().toString(), memberName.toString() ),
|
||||
memberType.getQualifiedName().toString() );
|
||||
return memberMatchingParameter( memberType, param, tokens );
|
||||
return memberMatchingPath( memberType, tokens );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,9 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
|
||||
private final @Nullable String containerType;
|
||||
private final List<Boolean> paramNullability;
|
||||
private final List<OrderBy> orderBys;
|
||||
|
||||
public CriteriaFinderMethod(
|
||||
CriteriaFinderMethod(
|
||||
AnnotationMetaEntity annotationMetaEntity,
|
||||
String methodName, String entity,
|
||||
@Nullable String containerType,
|
||||
|
@ -32,11 +33,13 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
String sessionType,
|
||||
String sessionName,
|
||||
List<String> fetchProfiles,
|
||||
List<OrderBy> orderBys,
|
||||
boolean addNonnullAnnotation) {
|
||||
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, sessionName, fetchProfiles,
|
||||
paramNames, paramTypes, addNonnullAnnotation );
|
||||
this.containerType = containerType;
|
||||
this.paramNullability = paramNullability;
|
||||
this.orderBys = orderBys;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -101,7 +104,38 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
}
|
||||
}
|
||||
declaration
|
||||
.append("\n\t);")
|
||||
.append("\n\t);");
|
||||
if ( !orderBys.isEmpty() ) {
|
||||
declaration.append("\n\tquery.orderBy(");
|
||||
boolean firstOrderBy = true;
|
||||
for ( OrderBy orderBy : orderBys ) {
|
||||
if ( firstOrderBy ) {
|
||||
firstOrderBy = false;
|
||||
}
|
||||
else {
|
||||
declaration.append(", ");
|
||||
}
|
||||
declaration
|
||||
.append("builder.")
|
||||
.append(orderBy.descending ? "desc" : "asc")
|
||||
.append('(');
|
||||
if ( orderBy.ignoreCase ) {
|
||||
declaration.append("builder.lower(");
|
||||
}
|
||||
declaration
|
||||
.append("entity.get(\"")
|
||||
.append(orderBy.fieldName)
|
||||
.append("\")");
|
||||
if ( orderBy.ignoreCase ) {
|
||||
declaration
|
||||
.append(')');
|
||||
}
|
||||
declaration
|
||||
.append(')');
|
||||
}
|
||||
declaration.append(");");
|
||||
}
|
||||
declaration
|
||||
.append("\n\treturn ")
|
||||
.append(sessionName)
|
||||
.append(".createQuery(query)");
|
||||
|
@ -207,4 +241,14 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
return type;
|
||||
}
|
||||
|
||||
static class OrderBy {
|
||||
String fieldName;
|
||||
boolean descending;
|
||||
boolean ignoreCase;
|
||||
public OrderBy(String fieldName, boolean descending, boolean ignoreCase) {
|
||||
this.fieldName = fieldName;
|
||||
this.descending = descending;
|
||||
this.ignoreCase = ignoreCase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue