HHH-17772 support Jakarta Data PageRequest as a parameter

This commit is contained in:
Gavin King 2024-02-25 23:07:29 +01:00
parent be448afdab
commit df84bcd84e
4 changed files with 80 additions and 33 deletions

View File

@ -11,7 +11,6 @@ import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel; import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants; import org.hibernate.jpamodelgen.util.Constants;
import org.hibernate.query.Order; import org.hibernate.query.Order;
import org.hibernate.query.Page;
import org.hibernate.query.SortDirection; import org.hibernate.query.SortDirection;
import java.util.ArrayList; import java.util.ArrayList;
@ -20,9 +19,13 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static org.hibernate.jpamodelgen.util.Constants.HIB_ORDER;
import static org.hibernate.jpamodelgen.util.Constants.HIB_PAGE;
import static org.hibernate.jpamodelgen.util.Constants.JD_LIMIT; import static org.hibernate.jpamodelgen.util.Constants.JD_LIMIT;
import static org.hibernate.jpamodelgen.util.Constants.JD_ORDER; 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_SORT; import static org.hibernate.jpamodelgen.util.Constants.JD_SORT;
import static org.hibernate.jpamodelgen.util.Constants.LIST;
import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES; import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES;
import static org.hibernate.jpamodelgen.util.TypeUtils.isPrimitive; import static org.hibernate.jpamodelgen.util.TypeUtils.isPrimitive;
@ -183,22 +186,30 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
void setPage(StringBuilder declaration, String paramName, String paramType) { void setPage(StringBuilder declaration, String paramName, String paramType) {
boolean jakartaLimit = JD_LIMIT.equals(paramType); boolean jakartaLimit = JD_LIMIT.equals(paramType);
if ( jakartaLimit || isUsingEntityManager() ) { boolean jakartaPageRequest = paramType.startsWith(JD_PAGE_REQUEST);
declaration if ( jakartaLimit || jakartaPageRequest
.append("\n\t\t\t.setFirstResult("); || isUsingEntityManager() ) {
if (jakartaLimit) { final String firstResult;
declaration.append("(int) "); final String maxResults;
if ( jakartaLimit ) {
firstResult = "(int) " + paramName + ".startAt() - 1";
maxResults = paramName + ".maxResults()";
}
else if ( jakartaPageRequest ) {
firstResult = "(int) (" + paramName + ".page()-1) * " + paramName + ".size()";
maxResults = paramName + ".size()";
}
else {
firstResult = paramName + ".getFirstResult()";
maxResults = paramName + ".getMaxResults()";
} }
declaration declaration
.append(paramName) .append("\n\t\t\t.setFirstResult(")
.append('.') .append(firstResult)
.append(jakartaLimit ? "startAt" : "getFirstResult") .append(")")
.append("())")
.append("\n\t\t\t.setMaxResults(") .append("\n\t\t\t.setMaxResults(")
.append(paramName) .append(maxResults)
.append('.') .append(")");
.append(jakartaLimit ? "maxResults" : "getMaxResults")
.append("())");
} }
else { else {
declaration declaration
@ -341,13 +352,14 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
} }
static boolean isPageParam(String parameterType) { static boolean isPageParam(String parameterType) {
return Page.class.getName().equals(parameterType) return HIB_PAGE.equals(parameterType)
|| JD_LIMIT.equals(parameterType); || JD_LIMIT.equals(parameterType)
|| parameterType.startsWith(JD_PAGE_REQUEST);
} }
static boolean isOrderParam(String parameterType) { static boolean isOrderParam(String parameterType) {
return parameterType.startsWith(Order.class.getName()) return parameterType.startsWith(HIB_ORDER)
|| parameterType.startsWith(List.class.getName() + "<" + Order.class.getName()) || parameterType.startsWith(LIST + "<" + HIB_ORDER)
|| parameterType.startsWith(JD_SORT) || parameterType.startsWith(JD_SORT)
|| parameterType.startsWith(JD_ORDER); || parameterType.startsWith(JD_ORDER);
} }

View File

@ -68,6 +68,7 @@ import static org.hibernate.internal.util.StringHelper.qualify;
import static org.hibernate.jpamodelgen.annotation.QueryMethod.isOrderParam; import static org.hibernate.jpamodelgen.annotation.QueryMethod.isOrderParam;
import static org.hibernate.jpamodelgen.annotation.QueryMethod.isPageParam; import static org.hibernate.jpamodelgen.annotation.QueryMethod.isPageParam;
import static org.hibernate.jpamodelgen.util.Constants.FIND; 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_SESSION;
import static org.hibernate.jpamodelgen.util.Constants.HIB_STATELESS_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.HQL;
@ -76,11 +77,13 @@ 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_FIND;
import static org.hibernate.jpamodelgen.util.Constants.JD_INSERT; 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_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_QUERY;
import static org.hibernate.jpamodelgen.util.Constants.JD_REPOSITORY; 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_SAVE;
import static org.hibernate.jpamodelgen.util.Constants.JD_SORT; 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.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.MUTINY_SESSION;
import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES; import static org.hibernate.jpamodelgen.util.Constants.SESSION_TYPES;
import static org.hibernate.jpamodelgen.util.Constants.SQL; import static org.hibernate.jpamodelgen.util.Constants.SQL;
@ -820,16 +823,17 @@ public class AnnotationMetaEntity extends AnnotationMeta {
validateFinderParameter( entity, parameter ); validateFinderParameter( entity, parameter );
} }
else { else {
final Types types = context.getTypeUtils();
final TypeMirror parameterType = parameter.asType(); final TypeMirror parameterType = parameter.asType();
if ( isOrderParam( parameterType.toString() ) ) { final String type = parameterType.toString();
boolean pageRequest = type.startsWith(JD_PAGE_REQUEST);
if ( isOrderParam(type) || pageRequest ) {
final TypeMirror typeArgument = getTypeArgument( parameterType ); final TypeMirror typeArgument = getTypeArgument( parameterType );
if ( typeArgument == null ) { if ( typeArgument == null ) {
context.message( parameter, "missing type of order (should be 'Order<? super " missingTypeArgError( entity.getSimpleName().toString(), parameter, pageRequest );
+ entity.getSimpleName() + ">')", Diagnostic.Kind.ERROR );
} }
else if ( !context.getTypeUtils().isSameType( typeArgument, entity.asType() ) ) { else if ( !types.isSameType( typeArgument, entity.asType() ) ) {
context.message( parameter, "mismatched type of order (should be 'Order<? super " wrongTypeArgError( entity.getSimpleName().toString(), parameter, pageRequest );
+ entity.getSimpleName() + ">')", Diagnostic.Kind.ERROR);
} }
} }
} }
@ -854,6 +858,24 @@ public class AnnotationMetaEntity extends AnnotationMeta {
); );
} }
private void wrongTypeArgError(String entity, VariableElement parameter, boolean pageRequest) {
context.message(parameter,
(pageRequest
? "mismatched type of page request (should be 'PageRequest<? super "
:"mismatched type of order (should be 'Order<? super ")
+ entity + ">')",
Diagnostic.Kind.ERROR );
}
private void missingTypeArgError(String entity, VariableElement parameter, boolean pageRequest) {
context.message(parameter,
(pageRequest
? "missing type of page request (should be 'PageRequest<? super "
: "missing type of order (should be 'Order<? super ")
+ entity + ">')",
Diagnostic.Kind.ERROR );
}
private List<OrderBy> orderByList(ExecutableElement method, TypeElement entityType) { private List<OrderBy> orderByList(ExecutableElement method, TypeElement entityType) {
final AnnotationMirror orderByList = final AnnotationMirror orderByList =
getAnnotationMirror( method, "jakarta.data.repository.OrderBy.List" ); getAnnotationMirror( method, "jakarta.data.repository.OrderBy.List" );
@ -898,14 +920,15 @@ public class AnnotationMetaEntity extends AnnotationMeta {
case DECLARED: case DECLARED:
final DeclaredType type = (DeclaredType) parameterType; final DeclaredType type = (DeclaredType) parameterType;
final String parameterTypeName = parameterType.toString(); final String parameterTypeName = parameterType.toString();
if ( parameterTypeName.startsWith( List.class.getName() ) ) { if ( parameterTypeName.startsWith( LIST ) ) {
for (TypeMirror arg : type.getTypeArguments()) { for (TypeMirror arg : type.getTypeArguments()) {
return getTypeArgument( arg ); return getTypeArgument( arg );
} }
} }
else if ( parameterTypeName.startsWith( Order.class.getName() ) else if ( parameterTypeName.startsWith( HIB_ORDER )
|| parameterTypeName.startsWith( JD_SORT ) || parameterTypeName.startsWith( JD_SORT )
|| parameterTypeName.startsWith( JD_ORDER )) { || parameterTypeName.startsWith( JD_ORDER )
|| parameterTypeName.startsWith( JD_PAGE_REQUEST ) ) {
for ( TypeMirror arg : type.getTypeArguments() ) { for ( TypeMirror arg : type.getTypeArguments() ) {
switch ( arg.getKind() ) { switch ( arg.getKind() ) {
case WILDCARD: case WILDCARD:
@ -1756,17 +1779,18 @@ public class AnnotationMetaEntity extends AnnotationMeta {
} }
} }
if ( returnType != null ) { if ( returnType != null ) {
final Types types = context.getTypeUtils();
for ( VariableElement parameter : method.getParameters() ) { for ( VariableElement parameter : method.getParameters() ) {
final TypeMirror parameterType = parameter.asType(); final TypeMirror parameterType = parameter.asType();
final TypeMirror typeArgument = getTypeArgument( parameterType ); final TypeMirror typeArgument = getTypeArgument( parameterType );
if ( isOrderParam( parameterType.toString() ) ) { final String type = parameterType.toString();
final boolean pageRequest = type.startsWith(JD_PAGE_REQUEST);
if ( isOrderParam( type ) || pageRequest) {
if ( typeArgument == null ) { if ( typeArgument == null ) {
context.message( parameter, "missing type of order (should be 'Order<? super " missingTypeArgError( returnType.toString(), parameter, pageRequest );
+ returnType + ">')", Diagnostic.Kind.ERROR );
} }
else if ( !context.getTypeUtils().isSameType(typeArgument, returnType) ) { else if ( !types.isSameType(typeArgument, returnType) ) {
context.message( parameter, "mismatched type of order (should be 'Order<? super " wrongTypeArgError( returnType.toString(), parameter, pageRequest );
+ returnType + ">')", Diagnostic.Kind.ERROR );
} }
} }
} }

View File

@ -69,9 +69,13 @@ public final class Constants {
public static final String JD_DELETE = "jakarta.data.repository.Delete"; public static final String JD_DELETE = "jakarta.data.repository.Delete";
public static final String JD_SAVE = "jakarta.data.repository.Save"; public static final String JD_SAVE = "jakarta.data.repository.Save";
public static final String JD_LIMIT = "jakarta.data.Limit"; public static final String JD_LIMIT = "jakarta.data.Limit";
public static final String JD_PAGE_REQUEST = "jakarta.data.page.PageRequest";
public static final String JD_SORT = "jakarta.data.Sort"; public static final String JD_SORT = "jakarta.data.Sort";
public static final String JD_ORDER = "jakarta.data.Order"; public static final String JD_ORDER = "jakarta.data.Order";
public static final String HIB_ORDER = "org.hibernate.query.Order";
public static final String HIB_PAGE = "org.hibernate.query.Page";
public static final String CHECK_HQL = "org.hibernate.annotations.processing.CheckHQL"; public static final String CHECK_HQL = "org.hibernate.annotations.processing.CheckHQL";
public static final String ENTITY_MANAGER = "jakarta.persistence.EntityManager"; public static final String ENTITY_MANAGER = "jakarta.persistence.EntityManager";

View File

@ -3,6 +3,7 @@ package org.hibernate.jpamodelgen.test.data;
import jakarta.data.Limit; import jakarta.data.Limit;
import jakarta.data.Order; import jakarta.data.Order;
import jakarta.data.Sort; import jakarta.data.Sort;
import jakarta.data.page.PageRequest;
import jakarta.data.repository.By; import jakarta.data.repository.By;
import jakarta.data.repository.Delete; import jakarta.data.repository.Delete;
import jakarta.data.repository.Find; import jakarta.data.repository.Find;
@ -94,4 +95,10 @@ public interface BookAuthorRepository {
@Query("select title from Book where title like :title order by isbn") @Query("select title from Book where title like :title order by isbn")
Stream<String> titles(String title); Stream<String> titles(String title);
@Query("from Book")
List<Book> everyBook1(PageRequest<? super Book> pageRequest);
@Find
List<Book> everyBook2(PageRequest<? super Book> pageRequest);
} }