HHH-17772 support KeysetAwareSlice from Jakarta Data
significant refactoring
This commit is contained in:
parent
6f00449af1
commit
9e5ce60ac1
|
@ -12,6 +12,7 @@ import org.hibernate.jpamodelgen.util.Constants;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.Constants.HIB_SESSION;
|
||||
import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFromLowerCamelCase;
|
||||
|
||||
/**
|
||||
|
@ -146,24 +147,23 @@ public abstract class AbstractFinderMethod extends AbstractQueryMethod {
|
|||
if ( isUsingEntityManager() ) {
|
||||
declaration
|
||||
.append(".unwrap(")
|
||||
.append(annotationMetaEntity.importType(Constants.HIB_SESSION))
|
||||
.append(annotationMetaEntity.importType(HIB_SESSION))
|
||||
.append(".class)\n\t\t\t");
|
||||
}
|
||||
}
|
||||
|
||||
void enableFetchProfile(StringBuilder declaration) {
|
||||
// if ( !usingEntityManager ) {
|
||||
// declaration
|
||||
// .append("\n\t\t\t.enableFetchProfile(")
|
||||
// .append(constantName())
|
||||
// .append(")");
|
||||
// }
|
||||
boolean enableFetchProfile(StringBuilder declaration, boolean unwrapped) {
|
||||
if ( !fetchProfiles.isEmpty() ) {
|
||||
unwrapQuery( declaration, unwrapped );
|
||||
unwrapped = true;
|
||||
}
|
||||
for ( String profile : fetchProfiles ) {
|
||||
declaration
|
||||
.append("\n\t\t\t.enableFetchProfile(")
|
||||
.append(profile)
|
||||
.append(")");
|
||||
}
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
void preamble(StringBuilder declaration) {
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
import org.hibernate.query.Order;
|
||||
import org.hibernate.query.SortDirection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -23,12 +23,16 @@ 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.HIB_SELECTION_QUERY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_KEYED_SLICE;
|
||||
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_PAGE_REQUEST;
|
||||
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.SESSION_TYPES;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.STREAM;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.isPrimitive;
|
||||
|
||||
/**
|
||||
|
@ -231,18 +235,19 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
|
|||
annotationMetaEntity.staticImport(Collectors.class.getName(), "toList");
|
||||
annotationMetaEntity.staticImport(Order.class.getName(), "by");
|
||||
declaration
|
||||
.append("\n\t\t\t.setOrder(new ")
|
||||
.append(annotationMetaEntity.importType(ArrayList.class.getName()))
|
||||
.append("<>() {{\n\t\t\t\t")
|
||||
.append("\n\t\t\t.setOrder(")
|
||||
.append(paramName)
|
||||
.append(".forEach(_sort -> add(")
|
||||
.append("by(")
|
||||
.append(".sorts().stream()")
|
||||
.append("\n\t\t\t\t\t")
|
||||
.append(".map(_sort -> by(")
|
||||
.append(annotationMetaEntity.importType(sortableEntityClass))
|
||||
.append(".class, ")
|
||||
.append("_sort.property()")
|
||||
.append(",\n\t\t\t\t\t\t")
|
||||
.append("_sort.isAscending() ? ASCENDING : DESCENDING, ")
|
||||
.append("_sort.ignoreCase())));\n\t\t\t}})");
|
||||
.append(".class, _sort.property(),")
|
||||
.append("\n\t\t\t\t\t\t\t")
|
||||
.append("_sort.isAscending() ? ASCENDING : DESCENDING,")
|
||||
.append("\n\t\t\t\t\t\t\t")
|
||||
.append("_sort.ignoreCase()))")
|
||||
.append("\n\t\t\t\t\t")
|
||||
.append(".collect(toList()))");
|
||||
}
|
||||
}
|
||||
else if ( paramType.startsWith(JD_SORT) && paramType.endsWith("...") ) {
|
||||
|
@ -345,10 +350,22 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
|
|||
}
|
||||
|
||||
void unwrapQuery(StringBuilder declaration, boolean unwrapped) {
|
||||
if ( !unwrapped ) {
|
||||
if ( !unwrapped && isUsingEntityManager() ) {
|
||||
declaration
|
||||
.append("\n\t\t\t.unwrap(")
|
||||
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
|
||||
.append("\n\t\t\t.unwrap(");
|
||||
final String selectionQuery = annotationMetaEntity.importType(HIB_SELECTION_QUERY);
|
||||
// final String className = getSortableEntityClass();
|
||||
// if ( className != null ) {
|
||||
// final String entityClass = annotationMetaEntity.importType(className);
|
||||
// declaration
|
||||
// .append("(Class<")
|
||||
// .append(selectionQuery)
|
||||
// .append("<")
|
||||
// .append(entityClass)
|
||||
// .append(">>) (Class) ");
|
||||
// }
|
||||
declaration
|
||||
.append(selectionQuery)
|
||||
.append(".class)");
|
||||
}
|
||||
}
|
||||
|
@ -361,11 +378,13 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
|
|||
}
|
||||
|
||||
static boolean isKeyedPageParam(String parameterType) {
|
||||
return parameterType.startsWith(HIB_KEYED_PAGE);
|
||||
return parameterType.startsWith(HIB_KEYED_PAGE)
|
||||
|| parameterType.startsWith(JD_PAGE_REQUEST);
|
||||
}
|
||||
|
||||
static boolean isKeyedResultList(String returnType) {
|
||||
return returnType.startsWith(HIB_KEYED_RESULT_LIST);
|
||||
return returnType.startsWith(HIB_KEYED_RESULT_LIST)
|
||||
|| returnType.startsWith(JD_KEYED_SLICE);
|
||||
}
|
||||
|
||||
static boolean isPageParam(String parameterType) {
|
||||
|
@ -380,4 +399,120 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
|
|||
|| parameterType.startsWith(JD_SORT)
|
||||
|| parameterType.startsWith(JD_ORDER);
|
||||
}
|
||||
|
||||
void makeKeyedPage(StringBuilder declaration, List<String> paramTypes) {
|
||||
annotationMetaEntity.importType("org.hibernate.query.Page");
|
||||
annotationMetaEntity.importType("jakarta.data.page.impl.KeysetAwareSliceRecord");
|
||||
annotationMetaEntity.importType("jakarta.data.page.PageRequest.Cursor");
|
||||
annotationMetaEntity.staticImport("org.hibernate.query.KeyedPage.KeyInterpretation", "*");
|
||||
for (int i = 0; i < paramTypes.size(); i++) {
|
||||
if ( isKeyedPageParam( paramTypes.get(i) ) ) {
|
||||
declaration
|
||||
.append(MAKE_KEYED_PAGE.replace("pageRequest", paramNames.get(i)))
|
||||
.append("\t\tvar results = ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final String MAKE_KEYED_SLICE
|
||||
= "\t\tvar cursors =\n" +
|
||||
"\t\t\t\tresults.getKeyList()\n" +
|
||||
"\t\t\t\t\t\t.stream()\n" +
|
||||
"\t\t\t\t\t\t.map(_key -> Cursor.forKeyset(_key.toArray()))\n" +
|
||||
"\t\t\t\t\t\t.collect(toList());\n" +
|
||||
"\t\tvar page =\n" +
|
||||
"\t\t\t\tPageRequest.of(Entity.class)\n" +
|
||||
"\t\t\t\t\t\t.sortBy(pageRequest.sorts())\n" +
|
||||
"\t\t\t\t\t\t.size(pageRequest.size())\n" +
|
||||
"\t\t\t\t\t\t.page(pageRequest.page() + 1);\n" +
|
||||
"\t\treturn new KeysetAwareSliceRecord<>( results.getResultList(), cursors, pageRequest,\n" +
|
||||
"\t\t\t\tresults.isLastPage() ? null : page.afterKeyset( results.getNextPage().getKey().toArray() ),\n" +
|
||||
"\t\t\t\tresults.isFirstPage() ? null : page.beforeKeyset( results.getPreviousPage().getKey().toArray() ) );\n";
|
||||
|
||||
static final String MAKE_KEYED_PAGE
|
||||
= "\t\tvar unkeyedPage =\n" +
|
||||
"\t\t\t\tPage.page(pageRequest.size(), (int) pageRequest.page()-1)\n" +
|
||||
"\t\t\t\t\t\t.keyedBy(pageRequest.sorts().stream()\n" +
|
||||
"\t\t\t\t\t\t\t\t.map(_sort -> by(Book.class, _sort.property(),\n" +
|
||||
"\t\t\t\t\t\t\t\t\t\t_sort.isAscending() ? ASCENDING : DESCENDING,\n" +
|
||||
"\t\t\t\t\t\t\t\t\t\t_sort.ignoreCase())).collect(toList()));\n" +
|
||||
"\t\tvar keyedPage =\n" +
|
||||
"\t\t\t\tpageRequest.cursor()\n" +
|
||||
"\t\t\t\t\t\t.map(_cursor -> {\n" +
|
||||
"\t\t\t\t\t\t\t@SuppressWarnings(\"unchecked\")\n" +
|
||||
"\t\t\t\t\t\t\tvar elements = (List<Comparable<?>>) _cursor.elements();\n" +
|
||||
"\t\t\t\t\t\t\treturn switch ( pageRequest.mode() ) {\n" +
|
||||
"\t\t\t\t\t\t\t\tcase CURSOR_NEXT -> unkeyedPage.withKey(elements, KEY_OF_LAST_ON_PREVIOUS_PAGE);\n" +
|
||||
"\t\t\t\t\t\t\t\tcase CURSOR_PREVIOUS -> unkeyedPage.withKey(elements, KEY_OF_FIRST_ON_NEXT_PAGE);\n" +
|
||||
"\t\t\t\t\t\t\t\tdefault -> unkeyedPage;\n" +
|
||||
"\t\t\t\t\t\t\t};\n" +
|
||||
"\t\t\t\t\t\t}).orElse(unkeyedPage);\n";
|
||||
|
||||
protected void executeSelect(
|
||||
StringBuilder declaration,
|
||||
List<String> paramTypes,
|
||||
@Nullable String containerType,
|
||||
boolean unwrapped,
|
||||
boolean mustUnwrap) {
|
||||
if ( containerType == null ) {
|
||||
declaration
|
||||
.append(".getSingleResult();");
|
||||
}
|
||||
else {
|
||||
switch (containerType) {
|
||||
case OPTIONAL:
|
||||
declaration
|
||||
.append(".uniqueResultOptional();");
|
||||
break;
|
||||
case STREAM:
|
||||
declaration
|
||||
.append(".getResultStream();");
|
||||
break;
|
||||
case LIST:
|
||||
declaration
|
||||
.append(".getResultList();");
|
||||
break;
|
||||
case HIB_KEYED_RESULT_LIST:
|
||||
for (int i = 0; i < paramTypes.size(); i++) {
|
||||
if ( isKeyedPageParam( paramTypes.get(i) ) ) {
|
||||
declaration
|
||||
.append(".getKeyedResultList(")
|
||||
.append(paramNames.get(i))
|
||||
.append(");");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JD_KEYED_SLICE:
|
||||
for (int i = 0; i < paramTypes.size(); i++) {
|
||||
if ( isKeyedPageParam( paramTypes.get(i) ) ) {
|
||||
final String entityClass = getSortableEntityClass();
|
||||
if ( entityClass == null ) {
|
||||
throw new AssertionFailure("entity class cannot be null");
|
||||
}
|
||||
else {
|
||||
final String entity = annotationMetaEntity.importType(entityClass);
|
||||
declaration
|
||||
.append("\t\t\t.getKeyedResultList(keyedPage);\n")
|
||||
.append(MAKE_KEYED_SLICE
|
||||
.replace("pageRequest", paramNames.get(i))
|
||||
.replace("Entity", entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ( isUsingEntityManager() && !unwrapped && mustUnwrap ) {
|
||||
declaration
|
||||
.append("\n\t\t\t")
|
||||
.append(".unwrap(")
|
||||
.append(annotationMetaEntity.importType(containerType))
|
||||
.append(".class);");
|
||||
|
||||
}
|
||||
else {
|
||||
declaration.append(';');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ import java.util.Collection;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -69,25 +70,7 @@ import static org.hibernate.jpamodelgen.annotation.AbstractQueryMethod.isSession
|
|||
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.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.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;
|
||||
|
@ -637,21 +620,19 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
}
|
||||
|
||||
private static boolean isLegalRawResultType(String containerTypeName) {
|
||||
return containerTypeName.equals(Constants.LIST)
|
||||
|| containerTypeName.equals(Constants.QUERY)
|
||||
|| containerTypeName.equals(Constants.HIB_QUERY);
|
||||
return LEGAL_RAW_RESULT_TYPES.contains( containerTypeName );
|
||||
}
|
||||
|
||||
private static boolean isLegalGenericResultType(String containerTypeName) {
|
||||
return containerTypeName.equals(Constants.LIST)
|
||||
|| containerTypeName.equals(Constants.STREAM)
|
||||
|| containerTypeName.equals(Constants.OPTIONAL)
|
||||
|| containerTypeName.equals(Constants.TYPED_QUERY)
|
||||
|| containerTypeName.equals(Constants.HIB_QUERY)
|
||||
|| containerTypeName.equals(Constants.HIB_SELECTION_QUERY)
|
||||
|| containerTypeName.equals(Constants.HIB_KEYED_RESULT_LIST);
|
||||
return LEGAL_GENERIC_RESULT_TYPES.contains( containerTypeName );
|
||||
}
|
||||
|
||||
private static final Set<String> LEGAL_RAW_RESULT_TYPES
|
||||
= Set.of(LIST, QUERY, HIB_QUERY);
|
||||
|
||||
private static final Set<String> LEGAL_GENERIC_RESULT_TYPES
|
||||
= Set.of(LIST, STREAM, OPTIONAL, TYPED_QUERY, HIB_QUERY, HIB_SELECTION_QUERY, HIB_KEYED_RESULT_LIST, JD_KEYED_SLICE);
|
||||
|
||||
private void addQueryMethod(
|
||||
ExecutableElement method,
|
||||
@Nullable TypeMirror returnType,
|
||||
|
|
|
@ -15,12 +15,10 @@ 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_KEYED_SLICE;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -71,7 +69,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
modifiers( declaration );
|
||||
preamble( declaration, paramTypes );
|
||||
nullChecks( paramTypes, declaration );
|
||||
createQuery( declaration );
|
||||
createCriteriaQuery( declaration );
|
||||
where( declaration, paramTypes );
|
||||
orderBy( paramTypes, declaration );
|
||||
executeQuery( declaration, paramTypes );
|
||||
|
@ -93,87 +91,95 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
private void executeQuery(StringBuilder declaration, List<String> paramTypes) {
|
||||
declaration
|
||||
.append('\n');
|
||||
if (dataRepository) {
|
||||
tryReturn( declaration, paramTypes );
|
||||
castResult( declaration );
|
||||
createQuery( declaration );
|
||||
boolean unwrapped = specialNeeds( declaration, paramTypes );
|
||||
execute( declaration, paramTypes, unwrapped );
|
||||
}
|
||||
|
||||
private void castResult(StringBuilder declaration) {
|
||||
if ( containerType == null && !fetchProfiles.isEmpty()
|
||||
&& isUsingEntityManager() ) {
|
||||
declaration
|
||||
.append("\ttry {\n\t");
|
||||
.append("(")
|
||||
.append(annotationMetaEntity.importType(entity))
|
||||
.append(") ");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean specialNeeds(StringBuilder declaration, List<String> paramTypes) {
|
||||
boolean unwrapped = !isUsingEntityManager();
|
||||
unwrapped = handleSpecialParameters( declaration, paramTypes, unwrapped );
|
||||
unwrapped = enableFetchProfile( declaration, unwrapped );
|
||||
unwrapped = unwrapIfOptional( declaration, unwrapped );
|
||||
if ( unwrapped ) {
|
||||
declaration.append("\n\t\t\t");
|
||||
}
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
private boolean unwrapIfOptional(StringBuilder declaration, boolean unwrapped) {
|
||||
if ( OPTIONAL.equals(containerType) ) {
|
||||
unwrapQuery(declaration, unwrapped);
|
||||
unwrapped = true;
|
||||
}
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
private void createQuery(StringBuilder declaration) {
|
||||
declaration
|
||||
.append("\treturn ")
|
||||
.append(sessionName)
|
||||
.append(".createQuery(query)");
|
||||
final boolean hasOrderParameter =
|
||||
paramTypes.stream().anyMatch(AbstractQueryMethod::isOrderParam);
|
||||
final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
|
||||
final boolean hasNativeReturnType =
|
||||
}
|
||||
|
||||
private void execute(StringBuilder declaration, List<String> paramTypes, boolean unwrapped) {
|
||||
final boolean mustUnwrap =
|
||||
containerType != null && containerType.startsWith("org.hibernate");
|
||||
final boolean unwrap =
|
||||
( hasOrderParameter || hasEnabledFetchProfiles || hasNativeReturnType )
|
||||
&& isUsingEntityManager();
|
||||
if ( unwrap ) {
|
||||
declaration
|
||||
.append("\n\t\t\t.unwrap(")
|
||||
.append(annotationMetaEntity.importType(HIB_SELECTION_QUERY))
|
||||
.append(".class)");
|
||||
}
|
||||
for ( int i = 0; i < paramNames.size(); i ++ ) {
|
||||
final String paramName = paramNames.get(i);
|
||||
final String paramType = paramTypes.get(i);
|
||||
if ( isPageParam(paramType) ) {
|
||||
setPage( declaration, paramName, paramType );
|
||||
}
|
||||
else if ( isOrderParam(paramType) && !isJakartaSortParam(paramType) ) {
|
||||
setOrder( declaration, true, paramName, paramType );
|
||||
}
|
||||
}
|
||||
enableFetchProfile(declaration);
|
||||
if ( containerType == null) {
|
||||
if ( unwrap || hasEnabledFetchProfiles ) {
|
||||
declaration.append("\n\t\t\t");
|
||||
}
|
||||
declaration
|
||||
.append(".getSingleResult()");
|
||||
}
|
||||
else if ( containerType.equals(OPTIONAL) ) {
|
||||
unwrapQuery( declaration, unwrap );
|
||||
declaration
|
||||
.append("\n\t\t\t.uniqueResultOptional()");
|
||||
}
|
||||
else if ( containerType.equals(STREAM) ) {
|
||||
if ( unwrap || hasOrderParameter || hasEnabledFetchProfiles ) {
|
||||
declaration.append("\n\t\t\t");
|
||||
}
|
||||
declaration
|
||||
.append(".getResultStream()");
|
||||
}
|
||||
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) {
|
||||
executeSelect( declaration, paramTypes, containerType, unwrapped, mustUnwrap );
|
||||
if ( dataRepository ) {
|
||||
declaration
|
||||
.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
private void createQuery(StringBuilder declaration) {
|
||||
private boolean handleSpecialParameters(StringBuilder declaration, List<String> paramTypes, boolean unwrapped) {
|
||||
if ( containerType == null || !containerType.equals(JD_KEYED_SLICE) ) {
|
||||
for ( int i = 0; i < paramNames.size(); i ++ ) {
|
||||
final String paramName = paramNames.get(i);
|
||||
final String paramType = paramTypes.get(i);
|
||||
if ( isPageParam(paramType) ) {
|
||||
setPage( declaration, paramName, paramType );
|
||||
}
|
||||
else if ( isOrderParam(paramType) && !isJakartaSortParam(paramType) ) {
|
||||
setOrder( declaration, unwrapped, paramName, paramType );
|
||||
unwrapped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
private void tryReturn(StringBuilder declaration, List<String> paramTypes) {
|
||||
if (dataRepository) {
|
||||
declaration
|
||||
.append("\ttry {\n");
|
||||
}
|
||||
if ( containerType != null
|
||||
&& containerType.equals(JD_KEYED_SLICE) ) {
|
||||
makeKeyedPage(declaration, paramTypes);
|
||||
}
|
||||
else {
|
||||
if ( dataRepository ) {
|
||||
declaration
|
||||
.append('\t');
|
||||
}
|
||||
declaration
|
||||
.append("\treturn ");
|
||||
}
|
||||
}
|
||||
|
||||
private void createCriteriaQuery(StringBuilder declaration) {
|
||||
declaration
|
||||
.append("\n\tvar builder = ")
|
||||
.append(sessionName)
|
||||
|
|
|
@ -80,7 +80,7 @@ public class IdFinderMethod extends AbstractFinderMethod {
|
|||
.append(".byId(")
|
||||
.append(annotationMetaEntity.importType(entity))
|
||||
.append(".class)");
|
||||
enableFetchProfile(declaration);
|
||||
enableFetchProfile( declaration, true );
|
||||
declaration
|
||||
.append("\n\t\t\t.load(")
|
||||
.append(paramName)
|
||||
|
|
|
@ -65,7 +65,7 @@ public class NaturalIdFinderMethod extends AbstractFinderMethod {
|
|||
.append(".byNaturalId(")
|
||||
.append(annotationMetaEntity.importType(entity))
|
||||
.append(".class)");
|
||||
enableFetchProfile( declaration );
|
||||
enableFetchProfile( declaration, true );
|
||||
for ( int i = 0; i < paramNames.size(); i ++ ) {
|
||||
if ( !isSessionParameter( paramTypes.get(i) ) ) {
|
||||
final String paramName = paramNames.get(i);
|
||||
|
|
|
@ -13,11 +13,14 @@ 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.HIB_QUERY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.HIB_SELECTION_QUERY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JD_KEYED_SLICE;
|
||||
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.Constants.QUERY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.TYPED_QUERY;
|
||||
import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFromLowerCamelCase;
|
||||
|
||||
/**
|
||||
|
@ -26,7 +29,7 @@ import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFr
|
|||
*/
|
||||
public class QueryMethod extends AbstractQueryMethod {
|
||||
private final String queryString;
|
||||
private final @Nullable String containerTypeName;
|
||||
private final @Nullable String containerType;
|
||||
private final boolean isUpdate;
|
||||
private final boolean isNative;
|
||||
private final List<OrderBy> orderBys;
|
||||
|
@ -38,7 +41,7 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
@Nullable
|
||||
String returnTypeName,
|
||||
@Nullable
|
||||
String containerTypeName,
|
||||
String containerType,
|
||||
List<String> paramNames,
|
||||
List<String> paramTypes,
|
||||
boolean isUpdate,
|
||||
|
@ -56,7 +59,7 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
belongsToDao, addNonnullAnnotation,
|
||||
dataRepository );
|
||||
this.queryString = queryString;
|
||||
this.containerTypeName = containerTypeName;
|
||||
this.containerType = containerType;
|
||||
this.isUpdate = isUpdate;
|
||||
this.isNative = isNative;
|
||||
this.orderBys = orderBys;
|
||||
|
@ -79,7 +82,7 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
|
||||
@Override
|
||||
boolean singleResult() {
|
||||
return containerTypeName == null;
|
||||
return containerType == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -93,14 +96,46 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
tryReturn( declaration );
|
||||
castResult( declaration, returnType );
|
||||
createQuery( declaration );
|
||||
boolean unwrapped = setParameters( paramTypes, declaration );
|
||||
unwrapped = orderBy( declaration, unwrapped);
|
||||
setParameters( paramTypes, declaration );
|
||||
boolean unwrapped = specialNeeds( paramTypes, declaration );
|
||||
execute( declaration, unwrapped );
|
||||
convertExceptions( declaration );
|
||||
closingBrace( declaration );
|
||||
return declaration.toString();
|
||||
}
|
||||
|
||||
private boolean specialNeeds(List<String> paramTypes, StringBuilder declaration) {
|
||||
boolean unwrapped;
|
||||
if ( containerType == null || !containerType.equals(JD_KEYED_SLICE) ) {
|
||||
unwrapped = handleSpecialParameters( paramTypes, declaration );
|
||||
unwrapped = orderBy( declaration, unwrapped );
|
||||
}
|
||||
else {
|
||||
unwrapped = !isUsingEntityManager();
|
||||
}
|
||||
unwrapped = unwrapIfOptional( declaration, unwrapped );
|
||||
if ( isUpdate || containerType == null || !isQueryType(containerType)) {
|
||||
declaration
|
||||
.append("\n\t\t\t");
|
||||
}
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
private boolean unwrapIfOptional(StringBuilder declaration, boolean unwrapped) {
|
||||
if ( OPTIONAL.equals(containerType) ) {
|
||||
unwrapQuery(declaration, unwrapped);
|
||||
unwrapped = true;
|
||||
}
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
private boolean isQueryType(String containerType) {
|
||||
return HIB_QUERY.equals(containerType)
|
||||
|| HIB_SELECTION_QUERY.equals(containerType)
|
||||
|| QUERY.equals(containerType)
|
||||
|| TYPED_QUERY.equals(containerType);
|
||||
}
|
||||
|
||||
private boolean orderBy(StringBuilder declaration, boolean unwrapped) {
|
||||
if ( !orderBys.isEmpty() && returnTypeName!=null ) {
|
||||
unwrapQuery( declaration, unwrapped );
|
||||
|
@ -155,7 +190,7 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
}
|
||||
|
||||
private void castResult(StringBuilder declaration, StringBuilder returnType) {
|
||||
if ( isNative && returnTypeName != null && containerTypeName == null
|
||||
if ( isNative && returnTypeName != null && containerType == null
|
||||
&& isUsingEntityManager() ) {
|
||||
// EntityManager.createNativeQuery() does not return TypedQuery,
|
||||
// so we need to cast to the entity type
|
||||
|
@ -168,13 +203,23 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
private void tryReturn(StringBuilder declaration) {
|
||||
if (dataRepository) {
|
||||
declaration
|
||||
.append("\ttry {\n\t");
|
||||
.append("\ttry {\n");
|
||||
}
|
||||
declaration
|
||||
.append("\t");
|
||||
if ( returnTypeName == null || !returnTypeName.equals("void") ) {
|
||||
if ( containerType != null
|
||||
&& containerType.equals(JD_KEYED_SLICE) ) {
|
||||
makeKeyedPage( declaration, paramTypes );
|
||||
}
|
||||
else {
|
||||
if ( dataRepository ) {
|
||||
declaration
|
||||
.append('\t');
|
||||
}
|
||||
declaration
|
||||
.append("return ");
|
||||
.append("\t");
|
||||
if ( returnTypeName == null || !returnTypeName.equals("void") ) {
|
||||
declaration
|
||||
.append("return ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,61 +236,30 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
private void execute(StringBuilder declaration, boolean unwrapped) {
|
||||
if ( isUpdate ) {
|
||||
declaration
|
||||
.append("\n\t\t\t.executeUpdate()");
|
||||
.append(".executeUpdate()");
|
||||
if ( "boolean".equals(returnTypeName) ) {
|
||||
declaration.append(" > 0");
|
||||
}
|
||||
}
|
||||
else if ( containerTypeName == null ) {
|
||||
declaration
|
||||
.append("\n\t\t\t.getSingleResult()");
|
||||
}
|
||||
else if ( containerTypeName.equals(OPTIONAL) ) {
|
||||
unwrapQuery( declaration, unwrapped );
|
||||
declaration
|
||||
.append("\n\t\t\t.uniqueResultOptional()");
|
||||
}
|
||||
else if ( containerTypeName.equals(STREAM) ) {
|
||||
declaration
|
||||
.append("\n\t\t\t.getResultStream()");
|
||||
}
|
||||
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(')');
|
||||
}
|
||||
}
|
||||
.append(';');
|
||||
}
|
||||
else {
|
||||
if ( isUsingEntityManager() && !unwrapped
|
||||
&& ( containerTypeName.startsWith("org.hibernate")
|
||||
|| isNative && returnTypeName != null ) ) {
|
||||
declaration
|
||||
.append("\n\t\t\t.unwrap(")
|
||||
.append(annotationMetaEntity.importType(containerTypeName))
|
||||
.append(".class)");
|
||||
|
||||
}
|
||||
final boolean mustUnwrap =
|
||||
containerType != null && containerType.startsWith("org.hibernate")
|
||||
|| isNative && returnTypeName != null;
|
||||
executeSelect( declaration, paramTypes, containerType, unwrapped, mustUnwrap );
|
||||
}
|
||||
declaration.append(';');
|
||||
if (dataRepository) {
|
||||
declaration.append('\n');
|
||||
if ( dataRepository ) {
|
||||
declaration
|
||||
.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setParameters(List<String> paramTypes, StringBuilder declaration) {
|
||||
boolean unwrapped = !isUsingEntityManager();
|
||||
private void setParameters(List<String> paramTypes, StringBuilder declaration) {
|
||||
for ( int i = 0; i < paramNames.size(); i++ ) {
|
||||
final String paramName = paramNames.get(i);
|
||||
final String paramType = paramTypes.get(i);
|
||||
if ( !isSessionParameter(paramType) ) {
|
||||
if ( !isSpecialParam(paramType) ) {
|
||||
final int ordinal = i+1;
|
||||
if ( queryString.contains(":" + paramName) ) {
|
||||
setNamedParameter( declaration, paramName );
|
||||
|
@ -253,12 +267,20 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
else if ( queryString.contains("?" + ordinal) ) {
|
||||
setOrdinalParameter( declaration, ordinal, paramName );
|
||||
}
|
||||
else if ( isPageParam(paramType) ) {
|
||||
setPage( declaration, paramName, paramType );
|
||||
}
|
||||
else if ( isOrderParam(paramType) ) {
|
||||
unwrapped = setOrder( declaration, unwrapped, paramName, paramType );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleSpecialParameters(List<String> paramTypes, StringBuilder declaration) {
|
||||
boolean unwrapped = !isUsingEntityManager();
|
||||
for ( int i = 0; i < paramNames.size(); i++ ) {
|
||||
final String paramName = paramNames.get(i);
|
||||
final String paramType = paramTypes.get(i);
|
||||
if ( isPageParam(paramType) ) {
|
||||
setPage( declaration, paramName, paramType );
|
||||
}
|
||||
else if ( isOrderParam(paramType) ) {
|
||||
unwrapped = setOrder( declaration, unwrapped, paramName, paramType );
|
||||
}
|
||||
}
|
||||
return unwrapped;
|
||||
|
@ -285,12 +307,12 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
private StringBuilder returnType() {
|
||||
StringBuilder type = new StringBuilder();
|
||||
boolean returnsUni = isReactive()
|
||||
&& (containerTypeName == null || LIST.equals(containerTypeName));
|
||||
&& (containerType == null || LIST.equals(containerType));
|
||||
if ( returnsUni ) {
|
||||
type.append(annotationMetaEntity.importType(Constants.UNI)).append('<');
|
||||
}
|
||||
if ( containerTypeName != null ) {
|
||||
type.append(annotationMetaEntity.importType(containerTypeName));
|
||||
if ( containerType != null ) {
|
||||
type.append(annotationMetaEntity.importType(containerType));
|
||||
if ( returnTypeName != null ) {
|
||||
type.append("<").append(annotationMetaEntity.importType(returnTypeName)).append(">");
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ public final class Constants {
|
|||
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_ORDER = "jakarta.data.Order";
|
||||
public static final String JD_KEYED_SLICE = "jakarta.data.page.KeysetAwareSlice";
|
||||
|
||||
public static final String HIB_ORDER = "org.hibernate.query.Order";
|
||||
public static final String HIB_PAGE = "org.hibernate.query.Page";
|
||||
|
@ -101,14 +102,14 @@ public final class Constants {
|
|||
public static final String LIST_ATTRIBUTE = "jakarta.persistence.metamodel.ListAttribute";
|
||||
public static final String MAP_ATTRIBUTE = "jakarta.persistence.metamodel.MapAttribute";
|
||||
|
||||
public static final String JAVA_OBJECT = Object.class.getName();
|
||||
public static final String ITERABLE = java.lang.Iterable.class.getName();
|
||||
public static final String COLLECTION = java.util.Collection.class.getName();
|
||||
public static final String LIST = java.util.List.class.getName();
|
||||
public static final String MAP = java.util.Map.class.getName();
|
||||
public static final String SET = java.util.Set.class.getName();
|
||||
public static final String OPTIONAL = java.util.Optional.class.getName();
|
||||
public static final String STREAM = java.util.stream.Stream.class.getName();
|
||||
public static final String JAVA_OBJECT = "java.lang.Object";
|
||||
public static final String ITERABLE = "java.lang.Iterable";
|
||||
public static final String COLLECTION = "java.util.Collection";
|
||||
public static final String LIST = "java.util.List";
|
||||
public static final String MAP = "java.util.Map";
|
||||
public static final String SET = "java.util.Set";
|
||||
public static final String OPTIONAL = "java.util.Optional";
|
||||
public static final String STREAM = "java.util.stream.Stream";
|
||||
|
||||
public static final Map<String, String> COLLECTIONS = Map.of(
|
||||
COLLECTION, Constants.COLLECTION_ATTRIBUTE,
|
||||
|
|
|
@ -19,7 +19,7 @@ import static org.hibernate.jpamodelgen.test.util.TestUtil.assertMetamodelClassG
|
|||
public class DaoTest extends CompilationTest {
|
||||
@Test
|
||||
@WithClasses({ Book.class, Dao.class, Bean.class, StatefulDao.class, StatelessDao.class })
|
||||
public void testGeneratedAnnotationNotGenerated() {
|
||||
public void testDao() {
|
||||
System.out.println( TestUtil.getMetaModelSourceAsString( Dao.class ) );
|
||||
System.out.println( TestUtil.getMetaModelSourceAsString( StatefulDao.class ) );
|
||||
System.out.println( TestUtil.getMetaModelSourceAsString( StatelessDao.class ) );
|
||||
|
|
|
@ -106,4 +106,16 @@ public interface BookAuthorRepository {
|
|||
@OrderBy("isbn")
|
||||
@OrderBy(value = "publicationDate", descending = true)
|
||||
List<Book> everyBook3(PageRequest<? super Book> pageRequest);
|
||||
|
||||
@Find
|
||||
KeysetAwareSlice<Book> everyBook4(PageRequest<Book> pageRequest);
|
||||
|
||||
@Find
|
||||
KeysetAwareSlice<Book> everyBook5(String title, PageRequest<Book> pageRequest);
|
||||
|
||||
@Query("from Book")
|
||||
KeysetAwareSlice<Book> everyBook6(PageRequest<Book> pageRequest);
|
||||
|
||||
@Query("from Book where title like :titlePattern")
|
||||
KeysetAwareSlice<Book> everyBook7(String titlePattern, PageRequest<Book> pageRequest);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue