HHH-17772 support @OrderBy for @Query methods
This commit is contained in:
parent
1196f72798
commit
568ad5804e
|
@ -11,7 +11,6 @@ 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;
|
||||
|
@ -21,7 +20,6 @@ import org.hibernate.jpamodelgen.util.Constants;
|
|||
import org.hibernate.jpamodelgen.validation.ProcessorSessionFactory;
|
||||
import org.hibernate.jpamodelgen.validation.Validation;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.query.Order;
|
||||
import org.hibernate.query.criteria.JpaEntityJoin;
|
||||
import org.hibernate.query.criteria.JpaRoot;
|
||||
import org.hibernate.query.criteria.JpaSelection;
|
||||
|
@ -67,26 +65,7 @@ import static javax.lang.model.util.ElementFilter.methodsIn;
|
|||
import static org.hibernate.internal.util.StringHelper.qualify;
|
||||
import static org.hibernate.jpamodelgen.annotation.QueryMethod.isOrderParam;
|
||||
import static org.hibernate.jpamodelgen.annotation.QueryMethod.isPageParam;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.FIND;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.HIB_ORDER;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.HIB_SESSION;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.HIB_STATELESS_SESSION;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.HQL;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.ITERABLE;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_DELETE;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_FIND;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_INSERT;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_ORDER;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_PAGE_REQUEST;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_QUERY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_REPOSITORY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_SAVE;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_SORT;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_UPDATE;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.LIST;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.MUTINY_SESSION;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.SQL;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.*;
|
||||
import static org.hibernate.jpamodelgen.util.NullnessUtil.castNonNull;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.containsAnnotation;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.determineAccessTypeForHierarchy;
|
||||
|
@ -1327,16 +1306,10 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
final List<String> paramNames = parameterNames( method );
|
||||
final List<String> paramTypes = parameterTypes( method );
|
||||
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
|
||||
if ( returnType != null && returnType.getKind() == TypeKind.DECLARED ) {
|
||||
final DeclaredType declaredType = (DeclaredType) returnType;
|
||||
if ( !declaredType.getTypeArguments().isEmpty() ) {
|
||||
context.message( method, mirror, value,
|
||||
"query result type may not be a generic type"
|
||||
+ " (change '" + returnType +
|
||||
"' to '" + context.getTypeUtils().erasure( returnType ) + "')",
|
||||
Diagnostic.Kind.ERROR );
|
||||
}
|
||||
}
|
||||
final DeclaredType resultType = resultType( method, returnType, mirror, value );
|
||||
final List<OrderBy> orderBys = resultType == null
|
||||
? emptyList()
|
||||
: orderByList( method, (TypeElement) resultType.asElement() );
|
||||
final QueryMethod attribute =
|
||||
new QueryMethod(
|
||||
this,
|
||||
|
@ -1351,6 +1324,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
repository,
|
||||
sessionType[0],
|
||||
sessionType[1],
|
||||
orderBys,
|
||||
context.addNonnullAnnotation(),
|
||||
jakartaDataRepository
|
||||
);
|
||||
|
@ -1369,6 +1343,24 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
}
|
||||
}
|
||||
|
||||
private @Nullable DeclaredType resultType(
|
||||
ExecutableElement method, @Nullable TypeMirror returnType, AnnotationMirror mirror, AnnotationValue value) {
|
||||
if ( returnType != null && returnType.getKind() == TypeKind.DECLARED ) {
|
||||
final DeclaredType resultType = (DeclaredType) returnType;
|
||||
if ( !resultType.getTypeArguments().isEmpty() ) {
|
||||
context.message(method, mirror, value,
|
||||
"query result type may not be a generic type"
|
||||
+ " (change '" + returnType +
|
||||
"' to '" + context.getTypeUtils().erasure(returnType) + "')",
|
||||
Diagnostic.Kind.ERROR );
|
||||
}
|
||||
return resultType;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInsertUpdateDelete(String hql) {
|
||||
final String trimmed = hql.trim();
|
||||
final String keyword = trimmed.length() > 6 ? trimmed.substring(0, 6) : "";
|
||||
|
|
|
@ -361,15 +361,4 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFromLowerCamelCase;
|
||||
|
@ -23,8 +24,9 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
private final @Nullable String containerTypeName;
|
||||
private final boolean isUpdate;
|
||||
private final boolean isNative;
|
||||
private final List<OrderBy> orderBys;
|
||||
|
||||
public QueryMethod(
|
||||
QueryMethod(
|
||||
AnnotationMetaEntity annotationMetaEntity,
|
||||
String methodName,
|
||||
String queryString,
|
||||
|
@ -39,6 +41,7 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
boolean belongsToDao,
|
||||
String sessionType,
|
||||
String sessionName,
|
||||
List<OrderBy> orderBys,
|
||||
boolean addNonnullAnnotation,
|
||||
boolean dataRepository) {
|
||||
super( annotationMetaEntity,
|
||||
|
@ -51,6 +54,7 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
this.containerTypeName = containerTypeName;
|
||||
this.isUpdate = isUpdate;
|
||||
this.isNative = isNative;
|
||||
this.orderBys = orderBys;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,12 +89,51 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
castResult( declaration, returnType );
|
||||
createQuery( declaration );
|
||||
boolean unwrapped = setParameters( paramTypes, declaration );
|
||||
unwrapped = orderBy( declaration, unwrapped);
|
||||
execute( declaration, unwrapped );
|
||||
convertExceptions( declaration );
|
||||
closingBrace( declaration );
|
||||
return declaration.toString();
|
||||
}
|
||||
|
||||
private boolean orderBy(StringBuilder declaration, boolean unwrapped) {
|
||||
if ( !orderBys.isEmpty() && returnTypeName!=null ) {
|
||||
unwrapQuery( declaration, unwrapped );
|
||||
declaration.append("\n\t\t\t.setOrder(");
|
||||
if ( orderBys.size() > 1) {
|
||||
annotationMetaEntity.staticImport(Arrays.class.getName(), "asList");
|
||||
declaration
|
||||
.append("asList(");
|
||||
}
|
||||
boolean first = true;
|
||||
for (OrderBy orderBy : orderBys) {
|
||||
if (first) {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
declaration
|
||||
.append(",\n\t\t\t\t\t\t\t");
|
||||
}
|
||||
declaration
|
||||
.append(annotationMetaEntity.importType(Constants.HIB_ORDER))
|
||||
.append(orderBy.descending ? ".desc(" : ".asc(")
|
||||
.append(annotationMetaEntity.importType(returnTypeName))
|
||||
.append(".class, \"")
|
||||
.append(orderBy.fieldName)
|
||||
.append("\")");
|
||||
}
|
||||
if ( orderBys.size() > 1) {
|
||||
declaration
|
||||
.append(')');
|
||||
}
|
||||
declaration.append(')');
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return unwrapped;
|
||||
}
|
||||
}
|
||||
|
||||
private void createQuery(StringBuilder declaration) {
|
||||
declaration
|
||||
.append(sessionName)
|
||||
|
|
|
@ -101,4 +101,9 @@ public interface BookAuthorRepository {
|
|||
|
||||
@Find
|
||||
List<Book> everyBook2(PageRequest<? super Book> pageRequest);
|
||||
|
||||
@Query("from Book")
|
||||
@OrderBy("isbn")
|
||||
@OrderBy(value = "publicationDate", descending = true)
|
||||
List<Book> everyBook3(PageRequest<? super Book> pageRequest);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue