HHH-17779 support new key-based pagination API in generator

This commit is contained in:
Gavin King 2024-02-27 21:06:30 +01:00
parent 711feda338
commit 8c9e4f68bf
6 changed files with 104 additions and 36 deletions

View File

@ -91,14 +91,12 @@ public abstract class AbstractFinderMethod extends AbstractQueryMethod {
.append(annotationMetaEntity.importType(entity))
.append("} by ");
long paramCount = paramTypes.stream()
.filter(type -> !isOrderParam(type) && !isPageParam(type)
&& !isSessionParameter(type))
.filter(type -> !isSpecialParam(type))
.count();
int count = 0;
for (int i = 0; i < paramTypes.size(); i++) {
String type = paramTypes.get(i);
if ( !isPageParam(type) && !isOrderParam(type)
&& !isSessionParameter(type) ) {
if ( !isSpecialParam(type) ) {
if ( count>0 ) {
if ( count + 1 == paramCount) {
declaration

View File

@ -19,6 +19,8 @@ import java.util.List;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
import static org.hibernate.jpamodelgen.util.Constants.HIB_KEYED_PAGE;
import static org.hibernate.jpamodelgen.util.Constants.HIB_KEYED_RESULT_LIST;
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;
@ -351,6 +353,21 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
}
}
static boolean isSpecialParam(String parameterType) {
return isPageParam(parameterType)
|| isOrderParam(parameterType)
|| isKeyedPageParam(parameterType)
|| isSessionParameter(parameterType);
}
static boolean isKeyedPageParam(String parameterType) {
return parameterType.startsWith(HIB_KEYED_PAGE);
}
static boolean isKeyedResultList(String returnType) {
return returnType.startsWith(HIB_KEYED_RESULT_LIST);
}
static boolean isPageParam(String parameterType) {
return HIB_PAGE.equals(parameterType)
|| JD_LIMIT.equals(parameterType)

View File

@ -63,9 +63,31 @@ import static java.util.stream.Collectors.toList;
import static javax.lang.model.util.ElementFilter.fieldsIn;
import static javax.lang.model.util.ElementFilter.methodsIn;
import static org.hibernate.internal.util.StringHelper.qualify;
import static org.hibernate.jpamodelgen.annotation.AbstractQueryMethod.isKeyedPageParam;
import static org.hibernate.jpamodelgen.annotation.AbstractQueryMethod.isKeyedResultList;
import static org.hibernate.jpamodelgen.annotation.AbstractQueryMethod.isSessionParameter;
import static org.hibernate.jpamodelgen.annotation.AbstractQueryMethod.isSpecialParam;
import static org.hibernate.jpamodelgen.annotation.QueryMethod.isOrderParam;
import static org.hibernate.jpamodelgen.annotation.QueryMethod.isPageParam;
import static org.hibernate.jpamodelgen.util.Constants.*;
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.SQL;
import static org.hibernate.jpamodelgen.util.NullnessUtil.castNonNull;
import static org.hibernate.jpamodelgen.util.TypeUtils.containsAnnotation;
import static org.hibernate.jpamodelgen.util.TypeUtils.determineAccessTypeForHierarchy;
@ -581,7 +603,15 @@ public class AnnotationMetaEntity extends AnnotationMeta {
}
break;
case 1:
if ( isLegalGenericResultType( typeElement.toString() ) ) {
final String typeName = typeElement.getQualifiedName().toString();
if ( isLegalGenericResultType(typeName) ) {
if ( isKeyedResultList(typeName)
&& method.getParameters().stream()
.noneMatch(param -> isKeyedPageParam(param.asType().toString()))) {
context.message(method,
"method with return type 'KeyedResultList' has no parameter of type 'KeyedPage'",
Diagnostic.Kind.ERROR);
}
addQueryMethod( method, typeArguments.get(0), typeElement );
}
else {
@ -618,7 +648,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|| containerTypeName.equals(Constants.OPTIONAL)
|| containerTypeName.equals(Constants.TYPED_QUERY)
|| containerTypeName.equals(Constants.HIB_QUERY)
|| containerTypeName.equals(Constants.HIB_SELECTION_QUERY);
|| containerTypeName.equals(Constants.HIB_SELECTION_QUERY)
|| containerTypeName.equals(Constants.HIB_KEYED_RESULT_LIST);
}
private void addQueryMethod(
@ -928,10 +959,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
}
private static boolean isFinderParameterMappingToAttribute(VariableElement param) {
final String type = param.asType().toString();
return !isSessionParameter( type )
&& !isPageParam( type )
&& !isOrderParam( type );
return !isSpecialParam( param.asType().toString() );
}
private String[] sessionTypeFromParameters(List<String> paramNames, List<String> paramTypes) {
@ -1790,10 +1818,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
}
private static boolean parameterIsMissing(String hql, int i, String param, String type) {
return !hasParameter(hql, i, param)
&& !isSessionParameter(type)
&& !isPageParam(type)
&& !isOrderParam(type);
return !hasParameter(hql, i, param) && !isSpecialParam(type);
}
private static boolean hasParameter(String hql, int i, String param) {
@ -1801,10 +1826,6 @@ public class AnnotationMetaEntity extends AnnotationMeta {
.matcher(hql).matches();
}
private static boolean isSessionParameter(String type) {
return SESSION_TYPES.contains(type);
}
private boolean usingReactiveSession(String sessionType) {
return Constants.MUTINY_SESSION.equals(sessionType);
}

View File

@ -15,7 +15,12 @@ import java.util.List;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
import static org.hibernate.jpamodelgen.util.Constants.HIB_KEYED_RESULT_LIST;
import static org.hibernate.jpamodelgen.util.Constants.HIB_SELECTION_QUERY;
import static org.hibernate.jpamodelgen.util.Constants.JD_SORT;
import static org.hibernate.jpamodelgen.util.Constants.LIST;
import static org.hibernate.jpamodelgen.util.Constants.OPTIONAL;
import static org.hibernate.jpamodelgen.util.Constants.STREAM;
import static org.hibernate.jpamodelgen.util.TypeUtils.isPrimitive;
/**
@ -107,7 +112,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
if ( unwrap ) {
declaration
.append("\n\t\t\t.unwrap(")
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
.append(annotationMetaEntity.importType(HIB_SELECTION_QUERY))
.append(".class)");
}
for ( int i = 0; i < paramNames.size(); i ++ ) {
@ -128,25 +133,38 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
declaration
.append(".getSingleResult()");
}
else if ( containerType.equals(Constants.OPTIONAL) ) {
else if ( containerType.equals(OPTIONAL) ) {
unwrapQuery( declaration, unwrap );
declaration
.append("\n\t\t\t.uniqueResultOptional()");
}
else if ( containerType.equals(Constants.STREAM) ) {
else if ( containerType.equals(STREAM) ) {
if ( unwrap || hasOrderParameter || hasEnabledFetchProfiles ) {
declaration.append("\n\t\t\t");
}
declaration
.append(".getResultStream()");
}
else if ( containerType.equals(Constants.LIST) ) {
else if ( containerType.equals(LIST) ) {
if ( unwrap || hasOrderParameter || hasEnabledFetchProfiles ) {
declaration.append("\n\t\t\t");
}
declaration
.append(".getResultList()");
}
else if ( containerType.equals(HIB_KEYED_RESULT_LIST) ) {
if ( unwrap || hasOrderParameter || hasEnabledFetchProfiles ) {
declaration.append("\n\t\t\t");
}
for (int i = 0; i < paramTypes.size(); i++) {
if ( isKeyedPageParam( paramTypes.get(i) ) ) {
declaration
.append(".getKeyedResultList(")
.append(paramNames.get(i))
.append(')');
}
}
}
declaration
.append(';');
if (dataRepository) {
@ -236,9 +254,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
for ( int i = 0; i < paramNames.size(); i ++ ) {
final String paramName = paramNames.get(i);
final String paramType = paramTypes.get(i);
if ( !isSessionParameter(paramType)
&& !isPageParam(paramType)
&& !isOrderParam(paramType) ) {
if ( !isSpecialParam(paramType) ) {
if ( first ) {
first = false;
}
@ -345,7 +361,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
private StringBuilder returnType() {
StringBuilder type = new StringBuilder();
boolean returnsUni = isReactive()
&& (containerType == null || Constants.LIST.equals(containerType));
&& (containerType == null || LIST.equals(containerType));
if ( returnsUni ) {
type.append(annotationMetaEntity.importType(Constants.UNI)).append('<');
}

View File

@ -13,6 +13,11 @@ import org.hibernate.jpamodelgen.util.Constants;
import java.util.Arrays;
import java.util.List;
import static org.hibernate.jpamodelgen.util.Constants.HIB_KEYED_RESULT_LIST;
import static org.hibernate.jpamodelgen.util.Constants.HIB_ORDER;
import static org.hibernate.jpamodelgen.util.Constants.LIST;
import static org.hibernate.jpamodelgen.util.Constants.OPTIONAL;
import static org.hibernate.jpamodelgen.util.Constants.STREAM;
import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFromLowerCamelCase;
/**
@ -115,7 +120,7 @@ public class QueryMethod extends AbstractQueryMethod {
.append(",\n\t\t\t\t\t\t\t");
}
declaration
.append(annotationMetaEntity.importType(Constants.HIB_ORDER))
.append(annotationMetaEntity.importType(HIB_ORDER))
.append(orderBy.descending ? ".desc(" : ".asc(")
.append(annotationMetaEntity.importType(returnTypeName))
.append(".class, \"")
@ -195,19 +200,29 @@ public class QueryMethod extends AbstractQueryMethod {
declaration
.append("\n\t\t\t.getSingleResult()");
}
else if ( containerTypeName.equals(Constants.OPTIONAL) ) {
else if ( containerTypeName.equals(OPTIONAL) ) {
unwrapQuery( declaration, unwrapped );
declaration
.append("\n\t\t\t.uniqueResultOptional()");
}
else if ( containerTypeName.equals(Constants.STREAM) ) {
else if ( containerTypeName.equals(STREAM) ) {
declaration
.append("\n\t\t\t.getResultStream()");
}
else if ( containerTypeName.equals(Constants.LIST) ) {
else if ( containerTypeName.equals(LIST) ) {
declaration
.append("\n\t\t\t.getResultList()");
}
else if ( containerTypeName.equals(HIB_KEYED_RESULT_LIST) ) {
for (int i = 0; i < paramTypes.size(); i++) {
if ( isKeyedPageParam( paramTypes.get(i) ) ) {
declaration
.append("\n\t\t\t.getKeyedResultList(")
.append(paramNames.get(i))
.append(')');
}
}
}
else {
if ( isUsingEntityManager() && !unwrapped
&& ( containerTypeName.startsWith("org.hibernate")
@ -270,7 +285,7 @@ public class QueryMethod extends AbstractQueryMethod {
private StringBuilder returnType() {
StringBuilder type = new StringBuilder();
boolean returnsUni = isReactive()
&& (containerTypeName == null || Constants.LIST.equals(containerTypeName));
&& (containerTypeName == null || LIST.equals(containerTypeName));
if ( returnsUni ) {
type.append(annotationMetaEntity.importType(Constants.UNI)).append('<');
}
@ -359,8 +374,7 @@ public class QueryMethod extends AbstractQueryMethod {
else {
return stem + "_"
+ paramTypes.stream()
.filter(type -> !isPageParam(type) && !isOrderParam(type)
&& !isSessionParameter(type))
.filter(type -> !isSpecialParam(type))
.map(StringHelper::unqualify)
.reduce((x,y) -> x + '_' + y)
.orElse("");

View File

@ -75,6 +75,8 @@ public final class Constants {
public static final String HIB_ORDER = "org.hibernate.query.Order";
public static final String HIB_PAGE = "org.hibernate.query.Page";
public static final String HIB_KEYED_PAGE = "org.hibernate.query.KeyedPage";
public static final String HIB_KEYED_RESULT_LIST = "org.hibernate.query.KeyedResultList";
public static final String CHECK_HQL = "org.hibernate.annotations.processing.CheckHQL";