HHH-17772 redesign + unify handling of sorting

This commit is contained in:
Gavin King 2024-02-29 19:19:23 +01:00
parent 4ce2d317e5
commit faec7c1a67
7 changed files with 463 additions and 332 deletions

View File

@ -159,9 +159,9 @@ boolean enableFetchProfile(StringBuilder declaration, boolean unwrapped) {
}
for ( String profile : fetchProfiles ) {
declaration
.append("\n\t\t\t.enableFetchProfile(")
.append("\t\t\t.enableFetchProfile(")
.append(profile)
.append(")");
.append(")\n");
}
return unwrapped;
}

View File

@ -12,10 +12,10 @@
import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static java.util.Collections.emptyList;
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;
@ -211,99 +211,130 @@ else if ( jakartaPageRequest ) {
maxResults = paramName + ".getMaxResults()";
}
declaration
.append("\n\t\t\t.setFirstResult(")
.append("\t\t\t.setFirstResult(")
.append(firstResult)
.append(")")
.append("\n\t\t\t.setMaxResults(")
.append(")\n")
.append("\t\t\t.setMaxResults(")
.append(maxResults)
.append(")");
.append(")\n");
}
else {
declaration
.append("\n\t\t\t.setPage(")
.append("\t\t\t.setPage(")
.append(paramName)
.append(")");
.append(")\n");
}
}
boolean setOrder(StringBuilder declaration, boolean unwrapped, String paramName, String paramType) {
unwrapQuery( declaration, unwrapped );
if ( paramType.startsWith(JD_ORDER) ) {
final String sortableEntityClass = getSortableEntityClass();
if ( sortableEntityClass != null ) {
annotationMetaEntity.staticImport("org.hibernate.query.SortDirection", "*");
annotationMetaEntity.staticImport(Collectors.class.getName(), "toList");
annotationMetaEntity.staticImport(HIB_ORDER, "by");
declaration
.append("\n\t\t\t.setOrder(")
.append(paramName)
.append(".sorts().stream()")
.append("\n\t\t\t\t\t")
.append(".map(_sort -> by(")
.append(annotationMetaEntity.importType(sortableEntityClass))
.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("...") ) {
final String sortableEntityClass = getSortableEntityClass();
if ( sortableEntityClass != null ) {
annotationMetaEntity.staticImport("org.hibernate.query.SortDirection", "*");
annotationMetaEntity.staticImport(Arrays.class.getName(), "asList");
annotationMetaEntity.staticImport(Collectors.class.getName(), "toList");
annotationMetaEntity.staticImport(HIB_ORDER, "by");
declaration
.append("\n\t\t\t.setOrder(asList(")
.append(paramName)
.append(").stream().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\t.collect(toList())\n\t\t\t)");
}
}
else if ( paramType.startsWith(JD_SORT) ) {
final String sortableEntityClass = getSortableEntityClass();
if ( sortableEntityClass != null ) {
annotationMetaEntity.staticImport("org.hibernate.query.SortDirection", "*");
declaration
.append("\n\t\t\t.setOrder(")
.append(annotationMetaEntity.importType(HIB_ORDER))
.append(".by(")
.append(annotationMetaEntity.importType(sortableEntityClass))
.append(".class, ")
.append(paramName)
.append(".property()")
.append(",\n\t\t\t\t\t")
.append(paramName)
.append(".isAscending() ? ASCENDING : DESCENDING")
.append("))");
}
}
else if ( paramType.endsWith("...") ) {
boolean applyOrder(
StringBuilder declaration, List<String> paramTypes,
@Nullable String containerType, boolean unwrapped) {
if ( !isJakartaKeyedSlice(containerType) && hasOrdering(paramTypes) ) {
unwrapQuery( declaration, unwrapped );
declaration
.append("\n\t\t\t.setOrder(")
.append(annotationMetaEntity.importType(LIST))
.append(".of(")
.append(paramName)
.append("))");
.append("\t\t\t.setOrder(_orders)\n");
return true;
}
else {
declaration
.append("\n\t\t\t.setOrder(")
.append(paramName)
.append(")");
}
return true;
return unwrapped;
}
void handlePageParameters(
StringBuilder declaration, List<String> paramTypes,
@Nullable String containerType) {
if ( !isJakartaKeyedSlice(containerType) ) {
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 );
}
// if ( isOrderParam(paramType) && !isJakartaSortParam(paramType) ) {
// setOrder( declaration, unwrapped, paramName, paramType );
// unwrapped = true;
// }
}
}
}
// boolean setOrder(StringBuilder declaration, boolean unwrapped, String paramName, String paramType) {
// unwrapQuery( declaration, unwrapped );
// if ( paramType.startsWith(JD_ORDER)
// || paramType.startsWith(JD_PAGE_REQUEST) ) {
// final String sortableEntityClass = getSortableEntityClass();
// if ( sortableEntityClass != null ) {
// annotationMetaEntity.staticImport("org.hibernate.query.SortDirection", "*");
// annotationMetaEntity.staticImport(Collectors.class.getName(), "toList");
// annotationMetaEntity.staticImport(HIB_ORDER, "by");
// declaration
// .append("\n\t\t\t.setOrder(")
// .append(paramName)
// .append(".sorts().stream()")
// .append("\n\t\t\t\t\t")
// .append(".map(_sort -> by(")
// .append(annotationMetaEntity.importType(sortableEntityClass))
// .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("...") ) {
// final String sortableEntityClass = getSortableEntityClass();
// if ( sortableEntityClass != null ) {
// annotationMetaEntity.staticImport("org.hibernate.query.SortDirection", "*");
// annotationMetaEntity.staticImport(Arrays.class.getName(), "asList");
// annotationMetaEntity.staticImport(Collectors.class.getName(), "toList");
// annotationMetaEntity.staticImport(HIB_ORDER, "by");
// declaration
// .append("\n\t\t\t.setOrder(asList(")
// .append(paramName)
// .append(").stream().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\t.collect(toList())\n\t\t\t)");
// }
// }
// else if ( paramType.startsWith(JD_SORT) ) {
// final String sortableEntityClass = getSortableEntityClass();
// if ( sortableEntityClass != null ) {
// annotationMetaEntity.staticImport("org.hibernate.query.SortDirection", "*");
// declaration
// .append("\n\t\t\t.setOrder(")
// .append(annotationMetaEntity.importType(HIB_ORDER))
// .append(".by(")
// .append(annotationMetaEntity.importType(sortableEntityClass))
// .append(".class, ")
// .append(paramName)
// .append(".property()")
// .append(",\n\t\t\t\t\t")
// .append(paramName)
// .append(".isAscending() ? ASCENDING : DESCENDING")
// .append("))");
// }
// }
// else if ( paramType.endsWith("...") ) {
// declaration
// .append("\n\t\t\t.setOrder(")
// .append(annotationMetaEntity.importType(LIST))
// .append(".of(")
// .append(paramName)
// .append("))");
// }
// else {
// declaration
// .append("\n\t\t\t.setOrder(")
// .append(paramName)
// .append(")");
// }
// return true;
// }
void convertExceptions(StringBuilder declaration) {
if (dataRepository) {
declaration
@ -349,7 +380,7 @@ static void closingBrace(StringBuilder declaration) {
void unwrapQuery(StringBuilder declaration, boolean unwrapped) {
if ( !unwrapped && isUsingEntityManager() ) {
declaration
.append("\n\t\t\t.unwrap(");
.append("\t\t\t.unwrap(");
final String selectionQuery = annotationMetaEntity.importType(HIB_SELECTION_QUERY);
// final String className = getSortableEntityClass();
// if ( className != null ) {
@ -363,7 +394,7 @@ void unwrapQuery(StringBuilder declaration, boolean unwrapped) {
// }
declaration
.append(selectionQuery)
.append(".class)");
.append(".class)\n");
}
}
@ -388,7 +419,8 @@ static boolean isOrderParam(String parameterType) {
return parameterType.startsWith(HIB_ORDER)
|| parameterType.startsWith(LIST + "<" + HIB_ORDER)
|| parameterType.startsWith(JD_SORT)
|| parameterType.startsWith(JD_ORDER);
|| parameterType.startsWith(JD_ORDER)
|| parameterType.startsWith(JD_PAGE_REQUEST);
}
static boolean isJakartaKeyedSlice(@Nullable String containerType) {
@ -421,43 +453,44 @@ void makeKeyedPage(StringBuilder declaration, List<String> paramTypes) {
}
static final String MAKE_KEYED_SLICE
= "\t\tvar cursors =\n" +
"\t\t\t\tresults.getKeyList()\n" +
= "\t\tvar _cursors =\n" +
"\t\t\t\t_results.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\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, totalResults, 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";
"\t\treturn new KeysetAwareSliceRecord<>( _results.getResultList(), _cursors, _totalResults, pageRequest,\n" +
"\t\t\t\t_results.isLastPage() ? null : _page.afterKeyset(_results.getNextPage().getKey().toArray()),\n" +
"\t\t\t\t_results.isFirstPage() ? null : _page.beforeKeyset(_results.getPreviousPage().getKey().toArray()) );\n";
static final String MAKE_KEYED_PAGE
= "\tvar unkeyedPage =\n" +
= "\tvar _unkeyedPage =\n" +
"\t\t\tpage(pageRequest.size(), (int) pageRequest.page()-1)\n" +
"\t\t\t\t\t.keyedBy(pageRequest.sorts().stream()\n" +
"\t\t\t\t\t\t\t.map(_sort -> by(Entity.class, _sort.property(),\n" +
"\t\t\t\t\t\t\t\t\t_sort.isAscending() ? ASCENDING : DESCENDING,\n" +
"\t\t\t\t\t\t\t\t\t_sort.ignoreCase())).collect(toList()));\n" +
"\tvar keyedPage =\n" +
"\t\t\t\t\t.keyedBy(_orders);\n" +
"\tvar _keyedPage =\n" +
"\t\t\tpageRequest.cursor()\n" +
"\t\t\t\t\t.map(_cursor -> {\n" +
"\t\t\t\t\t\t@SuppressWarnings(\"unchecked\")\n" +
"\t\t\t\t\t\tvar elements = (List<Comparable<?>>) _cursor.elements();\n" +
"\t\t\t\t\t\tvar _elements = (List<Comparable<?>>) _cursor.elements();\n" +
"\t\t\t\t\t\treturn switch ( pageRequest.mode() ) {\n" +
"\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\tcase CURSOR_PREVIOUS -> unkeyedPage.withKey(elements, KEY_OF_FIRST_ON_NEXT_PAGE);\n" +
"\t\t\t\t\t\t\tdefault -> unkeyedPage;\n" +
"\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\tcase CURSOR_PREVIOUS -> _unkeyedPage.withKey(_elements, KEY_OF_FIRST_ON_NEXT_PAGE);\n" +
"\t\t\t\t\t\t\tdefault -> _unkeyedPage;\n" +
"\t\t\t\t\t\t};\n" +
"\t\t\t\t\t}).orElse(unkeyedPage);\n";
"\t\t\t\t\t}).orElse(_unkeyedPage);\n";
void createQuery(StringBuilder declaration) {}
void setParameters(StringBuilder declaration, List<String> paramTypes) {}
List<OrderBy> getOrderBys() {
return emptyList();
}
void tryReturn(StringBuilder declaration, List<String> paramTypes, @Nullable String containerType) {
if ( isJakartaKeyedSlice(containerType) ) {
makeKeyedPage( declaration, paramTypes );
@ -472,13 +505,7 @@ void tryReturn(StringBuilder declaration, List<String> paramTypes, @Nullable Str
declaration
.append('\t');
}
declaration
.append("\tlong totalResults = ");
createQuery( declaration );
setParameters( declaration, paramTypes );
unwrapQuery( declaration, !isUsingEntityManager() );
declaration
.append("\n\t\t\t\t\t\t.getResultCount();\n");
totalResults(declaration, paramTypes);
}
if ( dataRepository ) {
declaration
@ -503,7 +530,7 @@ void tryReturn(StringBuilder declaration, List<String> paramTypes, @Nullable Str
.append("var");
}
declaration
.append(" results = ");
.append(" _results = ");
}
else {
if ( !"void".equals(returnTypeName) ) {
@ -513,6 +540,129 @@ void tryReturn(StringBuilder declaration, List<String> paramTypes, @Nullable Str
}
}
private void totalResults(StringBuilder declaration, List<String> paramTypes) {
declaration
.append("\tlong _totalResults = ");
createQuery( declaration );
setParameters( declaration, paramTypes );
unwrapQuery( declaration, !isUsingEntityManager() );
declaration
.append("\t\t\t\t\t\t.getResultCount();\n");
}
void collectOrdering(StringBuilder declaration, List<String> paramTypes) {
final String entityClass = getSortableEntityClass();
if ( hasOrdering(paramTypes) ) {
if ( entityClass != null ) {
declaration
.append("\tvar _orders = new ")
.append(annotationMetaEntity.importType("java.util.ArrayList"))
.append("<")
.append(annotationMetaEntity.importType(HIB_ORDER))
.append("<? super ")
.append(annotationMetaEntity.importType(entityClass))
.append(">>();\n");
// static orders declared using @OrderBy must come first
for ( OrderBy orderBy : getOrderBys() ) {
declaration
.append("\t_orders.add(")
.append(annotationMetaEntity.staticImport(HIB_ORDER, "by"))
.append('(')
.append(annotationMetaEntity.importType(entityClass))
.append(".class, \"")
.append(orderBy.fieldName)
.append("\", ")
// .append("\n\t\t\t\t\t\t")
.append(orderBy.descending ? "DESCENDING" : "ASCENDING")
.append(", ")
// .append("\n\t\t\t\t\t\t")
.append(orderBy.ignoreCase)
.append("));\n");
}
for (int i = 0; i < paramTypes.size(); i++) {
final String type = paramTypes.get(i);
final String name = paramNames.get(i);
if ( type.startsWith(HIB_ORDER) && type.endsWith("...") ) {
declaration
.append("\tfor (var _sort : ")
.append(name)
.append(") {\n")
.append("\t\t_orders.add(_sort);\n")
.append("\t}\n");
}
else if ( type.startsWith(HIB_ORDER) ) {
declaration
.append("\t_orders.add(")
.append(name)
.append(");\n");
}
else if ( type.startsWith(LIST + "<" + HIB_ORDER) ) {
declaration
.append("\t_orders.addAll(")
.append(name)
.append(");\n");
}
else if ( type.startsWith(JD_ORDER)
|| type.startsWith(JD_PAGE_REQUEST) ) {
declaration
.append("\tfor (var _sort : ")
.append(name)
.append(".sorts()) {\n")
.append("\t\t_orders.add(")
.append(annotationMetaEntity.staticImport(HIB_ORDER, "by"))
.append('(')
.append(annotationMetaEntity.importType(entityClass))
.append(".class, _sort.property(),")
.append("\n\t\t\t\t\t\t")
.append("_sort.isAscending() ? ASCENDING : DESCENDING,")
.append("\n\t\t\t\t\t\t")
.append("_sort.ignoreCase()));\n")
.append("\t}\n");
}
else if ( type.startsWith(JD_SORT) && type.endsWith("...") ) {
// almost identical
declaration
.append("\tfor (var _sort : ")
.append(name)
.append(") {\n")
.append("\t\t_orders.add(")
.append(annotationMetaEntity.staticImport(HIB_ORDER, "by"))
.append('(')
.append(annotationMetaEntity.importType(entityClass))
.append(".class, _sort.property(),")
.append("\n\t\t\t\t\t\t")
.append("_sort.isAscending() ? ASCENDING : DESCENDING,")
.append("\n\t\t\t\t\t\t")
.append("_sort.ignoreCase()));\n")
.append("\t}\n");
}
else if ( type.startsWith(JD_SORT) ) {
declaration
.append("\t_orders.add(")
.append(annotationMetaEntity.staticImport(HIB_ORDER, "by"))
.append('(')
.append(annotationMetaEntity.importType(entityClass))
.append(".class, ")
.append(name)
.append(".property(),")
.append("\n\t\t\t\t\t\t")
.append(name)
.append(".isAscending() ? ASCENDING : DESCENDING,")
.append("\n\t\t\t\t\t\t")
.append(name)
.append(".ignoreCase()));\n");
}
}
}
}
}
private boolean hasOrdering(List<String> paramTypes) {
return paramTypes.stream().anyMatch(AbstractQueryMethod::isOrderParam)
|| !getOrderBys().isEmpty();
}
boolean unwrapIfNecessary(StringBuilder declaration, @Nullable String containerType, boolean unwrapped) {
if ( OPTIONAL.equals(containerType) || isJakartaKeyedSlice(containerType) ) {
unwrapQuery( declaration, unwrapped );
@ -527,6 +677,8 @@ protected void executeSelect(
@Nullable String containerType,
boolean unwrapped,
boolean mustUnwrap) {
declaration
.append("\t\t\t");
if ( containerType == null ) {
declaration
.append(".getSingleResult();");
@ -558,7 +710,7 @@ protected void executeSelect(
.append(implType(containerType))
.append('(')
.append(parameterName(JD_PAGE_REQUEST, paramTypes, paramNames))
.append(", results);\n");
.append(", _results);\n");
break;
case JD_PAGE:
declaration
@ -567,7 +719,7 @@ protected void executeSelect(
.append(implType(containerType))
.append('(')
.append(parameterName(JD_PAGE_REQUEST, paramTypes, paramNames))
.append(", results, totalResults);\n");
.append(", _results, _totalResults);\n");
break;
case JD_KEYED_SLICE:
case JD_KEYED_PAGE:
@ -577,7 +729,7 @@ protected void executeSelect(
}
else {
declaration
.append("\t\t\t.getKeyedResultList(keyedPage);\n");
.append(".getKeyedResultList(_keyedPage);\n");
annotationMetaEntity.importType("jakarta.data.page.PageRequest");
annotationMetaEntity.importType("jakarta.data.page.PageRequest.Cursor");
String fragment = MAKE_KEYED_SLICE
@ -586,7 +738,7 @@ protected void executeSelect(
.replace("Entity", annotationMetaEntity.importType(entityClass))
.replace("KeysetAwareSliceRecord", implType(containerType));
if ( JD_KEYED_SLICE.equals(containerType) ) {
fragment = fragment.replace("totalResults, ", "");
fragment = fragment.replace("_totalResults, ", "");
}
declaration
.append(fragment);
@ -595,7 +747,7 @@ protected void executeSelect(
default:
if ( isUsingEntityManager() && !unwrapped && mustUnwrap ) {
declaration
.append("\n\t\t\t")
.append("\t\t\t")
.append(".unwrap(")
.append(annotationMetaEntity.importType(containerType))
.append(".class);");

View File

@ -8,14 +8,10 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.jpamodelgen.util.Constants;
import org.hibernate.query.NullPrecedence;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
import static org.hibernate.jpamodelgen.util.Constants.JD_SORT;
import static org.hibernate.jpamodelgen.util.Constants.LIST;
import static org.hibernate.jpamodelgen.util.TypeUtils.isPrimitive;
@ -59,6 +55,11 @@ boolean singleResult() {
return containerType == null;
}
@Override
List<OrderBy> getOrderBys() {
return orderBys;
}
@Override
public String getAttributeDeclarationString() {
final List<String> paramTypes = parameterTypes();
@ -69,7 +70,7 @@ public String getAttributeDeclarationString() {
nullChecks( paramTypes, declaration );
createCriteriaQuery( declaration );
where( declaration, paramTypes );
orderBy( paramTypes, declaration );
// orderBy( paramTypes, declaration );
executeQuery( declaration, paramTypes );
convertExceptions( declaration );
closingBrace( declaration );
@ -83,16 +84,19 @@ private void preamble(StringBuilder declaration, List<String> paramTypes) {
.append(methodName);
parameters(paramTypes, declaration);
declaration
.append(" {");
.append(" {\n");
}
private void executeQuery(StringBuilder declaration, List<String> paramTypes) {
declaration
.append('\n');
collectOrdering( declaration, paramTypes );
tryReturn( declaration, paramTypes, containerType );
castResult( declaration );
createQuery( declaration );
boolean unwrapped = specialNeeds( declaration, paramTypes );
handlePageParameters( declaration, paramTypes, containerType );
boolean unwrapped = specialNeeds( declaration );
unwrapped = applyOrder( declaration, paramTypes, containerType, unwrapped );
execute( declaration, paramTypes, unwrapped );
}
@ -106,14 +110,13 @@ && isUsingEntityManager() ) {
}
}
private boolean specialNeeds(StringBuilder declaration, List<String> paramTypes) {
private boolean specialNeeds(StringBuilder declaration) {
boolean unwrapped = !isUsingEntityManager();
unwrapped = handleSpecialParameters( declaration, paramTypes, unwrapped );
unwrapped = enableFetchProfile( declaration, unwrapped );
unwrapped = unwrapIfNecessary( declaration, containerType, unwrapped );
if ( unwrapped ) {
declaration.append("\n\t\t\t");
}
// if ( unwrapped ) {
// declaration.append("\n\t\t\t");
// }
return unwrapped;
}
@ -121,7 +124,7 @@ private boolean specialNeeds(StringBuilder declaration, List<String> paramTypes)
void createQuery(StringBuilder declaration) {
declaration
.append(sessionName)
.append(".createQuery(query)");
.append(".createQuery(_query)\n");
}
private void execute(StringBuilder declaration, List<String> paramTypes, boolean unwrapped) {
@ -134,37 +137,20 @@ private void execute(StringBuilder declaration, List<String> paramTypes, boolean
}
}
private boolean handleSpecialParameters(StringBuilder declaration, List<String> paramTypes, boolean unwrapped) {
if ( !isJakartaKeyedSlice(containerType) ) {
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 createCriteriaQuery(StringBuilder declaration) {
declaration
.append("\n\tvar builder = ")
.append("\tvar _builder = ")
.append(sessionName)
.append(isUsingEntityManager()
? ".getEntityManagerFactory()"
: ".getFactory()")
.append(".getCriteriaBuilder();")
.append("\n\tvar query = builder.createQuery(")
.append(".getCriteriaBuilder();\n")
.append("\tvar _query = _builder.createQuery(")
.append(annotationMetaEntity.importType(entity))
.append(".class);")
.append("\n\tvar entity = query.from(")
.append(".class);\n")
.append("\tvar _entity = _query.from(")
.append(annotationMetaEntity.importType(entity))
.append(".class);");
.append(".class);\n");
}
private void nullChecks(List<String> paramTypes, StringBuilder declaration) {
@ -179,55 +165,55 @@ private void nullChecks(List<String> paramTypes, StringBuilder declaration) {
private static void nullCheck(StringBuilder declaration, String paramName) {
declaration
.append("\n\tif (")
.append("\tif (")
.append(paramName)
.append(" == null) throw new IllegalArgumentException(\"Null ")
.append(paramName)
.append("\");");
}
private void orderBy(List<String> paramTypes, StringBuilder declaration) {
final boolean hasSortParameter =
paramTypes.stream().anyMatch(CriteriaFinderMethod::isJakartaSortParam);
if ( !orderBys.isEmpty() || hasSortParameter ) {
declaration.append("\n\tquery.orderBy(");
}
boolean firstOrderBy = true;
if ( !orderBys.isEmpty() ) {
for ( OrderBy orderBy : orderBys ) {
if ( firstOrderBy ) {
firstOrderBy = false;
}
else {
declaration.append(',');
}
orderBy(declaration, orderBy);
}
}
if ( hasSortParameter ) {
for ( int i = 0; i < paramNames.size(); i ++ ) {
final String paramName = paramNames.get(i);
final String paramType = paramTypes.get(i);
//TODO: Jakarta Order!!
if ( isJakartaSortParam(paramType) ) {
if ( firstOrderBy ) {
firstOrderBy = false;
}
else {
declaration.append(',');
}
orderBy(declaration, paramName, paramType.endsWith("..."));
}
}
}
if ( !orderBys.isEmpty() || hasSortParameter ) {
declaration.append("\n\t);");
}
.append("\");\n");
}
//
// private void orderBy(List<String> paramTypes, StringBuilder declaration) {
// final boolean hasSortParameter =
// paramTypes.stream().anyMatch(CriteriaFinderMethod::isJakartaSortParam);
// if ( !orderBys.isEmpty() || hasSortParameter ) {
// declaration.append("\n\t_query.orderBy(");
// }
// boolean firstOrderBy = true;
// if ( !orderBys.isEmpty() ) {
// for ( OrderBy orderBy : orderBys ) {
// if ( firstOrderBy ) {
// firstOrderBy = false;
// }
// else {
// declaration.append(',');
// }
// orderBy(declaration, orderBy);
// }
// }
// if ( hasSortParameter ) {
// for ( int i = 0; i < paramNames.size(); i ++ ) {
// final String paramName = paramNames.get(i);
// final String paramType = paramTypes.get(i);
// //TODO: Jakarta Order!!
// if ( isJakartaSortParam(paramType) ) {
// if ( firstOrderBy ) {
// firstOrderBy = false;
// }
// else {
// declaration.append(',');
// }
// orderBy(declaration, paramName, paramType.endsWith("..."));
// }
// }
// }
// if ( !orderBys.isEmpty() || hasSortParameter ) {
// declaration.append("\n\t);");
// }
// }
private void where(StringBuilder declaration, List<String> paramTypes) {
declaration
.append("\n\tquery.where(");
.append("\t_query.where(");
boolean first = true;
for ( int i = 0; i < paramNames.size(); i ++ ) {
final String paramName = paramNames.get(i);
@ -247,55 +233,55 @@ private void where(StringBuilder declaration, List<String> paramTypes) {
.append("\n\t);");
}
private static boolean isJakartaSortParam(String paramType) {
return paramType.startsWith(JD_SORT);
}
// private static boolean isJakartaSortParam(String paramType) {
// return paramType.startsWith(JD_SORT);
// }
//
// private static void orderBy(StringBuilder declaration, OrderBy orderBy) {
// declaration
// .append("\n\t\t")
// .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(')');
// }
private static void orderBy(StringBuilder declaration, OrderBy orderBy) {
declaration
.append("\n\t\t")
.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(')');
}
// private static final String ORDER_CONVERSION =
// "_builder.sort(_entity.get(_sort.property())," +
// "\n\t\t\t\t\t_sort.isAscending() ? ASCENDING : DESCENDING," +
// "\n\t\t\t\t\tNONE, _sort.ignoreCase())";
private static final String ORDER_CONVERSION =
"builder.sort(entity.get(_sort.property())," +
"\n\t\t\t\t\t_sort.isAscending() ? ASCENDING : DESCENDING," +
"\n\t\t\t\t\tNONE, _sort.ignoreCase())";
private void orderBy(StringBuilder declaration, String paramName, boolean variadic) {
// TODO: Sort.ignoreCase()
if ( variadic ) {
annotationMetaEntity.staticImport(Arrays.class.getName(), "asList");
annotationMetaEntity.staticImport(Collectors.class.getName(), "toList");
annotationMetaEntity.staticImport(NullPrecedence.class.getName(), "NONE");
declaration
.append("\n\t\tasList(")
.append(paramName)
.append(")\n\t\t\t.stream()\n\t\t\t.map(_sort -> ")
.append(ORDER_CONVERSION)
.append("\n\t\t\t)\n\t\t\t.collect(toList())");
}
else {
declaration
.append("\n\t\t")
.append(ORDER_CONVERSION.replace("_sort", paramName));
}
}
// private void orderBy(StringBuilder declaration, String paramName, boolean variadic) {
// // TODO: Sort.ignoreCase()
// if ( variadic ) {
// annotationMetaEntity.staticImport(Arrays.class.getName(), "asList");
// annotationMetaEntity.staticImport(Collectors.class.getName(), "toList");
// annotationMetaEntity.staticImport(NullPrecedence.class.getName(), "NONE");
// declaration
// .append("\n\t\tasList(")
// .append(paramName)
// .append(")\n\t\t\t.stream()\n\t\t\t.map(_sort -> ")
// .append(ORDER_CONVERSION)
// .append("\n\t\t\t)\n\t\t\t.collect(toList())");
// }
// else {
// declaration
// .append("\n\t\t")
// .append(ORDER_CONVERSION.replace("_sort", paramName));
// }
// }
private void parameter(StringBuilder declaration, int i, String paramName, String paramType) {
declaration
@ -305,14 +291,14 @@ private void parameter(StringBuilder declaration, int i, String paramName, Strin
.append(paramName)
.append("==null")
.append("\n\t\t\t\t? ")
.append("entity");
.append("_entity");
path( declaration, paramName );
declaration
.append(".isNull()")
.append("\n\t\t\t\t: ");
}
declaration
.append("builder.equal(entity");
.append("_builder.equal(_entity");
path( declaration, paramName );
declaration
.append(", ")

View File

@ -79,10 +79,10 @@ private void findWithFetchProfiles(StringBuilder declaration) {
declaration
.append(".byId(")
.append(annotationMetaEntity.importType(entity))
.append(".class)");
.append(".class)\n");
enableFetchProfile( declaration, true );
declaration
.append("\n\t\t\t.load(")
.append("\t\t\t.load(")
.append(paramName)
.append(");");
if (dataRepository) {

View File

@ -64,23 +64,23 @@ private void findBlockingly(StringBuilder declaration) {
declaration
.append(".byNaturalId(")
.append(annotationMetaEntity.importType(entity))
.append(".class)");
.append(".class)\n");
enableFetchProfile( declaration, true );
for ( int i = 0; i < paramNames.size(); i ++ ) {
if ( !isSessionParameter( paramTypes.get(i) ) ) {
final String paramName = paramNames.get(i);
declaration
.append("\n\t\t\t.using(")
.append("\t\t\t.using(")
.append(annotationMetaEntity.importType(entity + '_'))
.append('.')
.append(paramName)
.append(", ")
.append(paramName)
.append(")");
.append(")\n");
}
}
declaration
.append("\n\t\t\t.load();");
.append("\t\t\t.load();");
}
private void findReactively(StringBuilder declaration) {

View File

@ -10,15 +10,9 @@
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.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.LIST;
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;
/**
@ -83,6 +77,11 @@ boolean singleResult() {
return containerType == null;
}
@Override
List<OrderBy> getOrderBys() {
return orderBys;
}
@Override
public String getAttributeDeclarationString() {
final List<String> paramTypes = parameterTypes();
@ -91,78 +90,80 @@ public String getAttributeDeclarationString() {
comment( declaration );
modifiers( paramTypes, declaration );
preamble( declaration, returnType, paramTypes );
collectOrdering( declaration, paramTypes );
tryReturn( declaration, paramTypes, containerType );
castResult( declaration, returnType );
createQuery( declaration );
setParameters( declaration, paramTypes );
boolean unwrapped = specialNeeds( paramTypes, declaration );
handlePageParameters( declaration, paramTypes, containerType );
boolean unwrapped = specialNeeds( declaration );
unwrapped = applyOrder( declaration, paramTypes, containerType, unwrapped );
execute( declaration, unwrapped );
convertExceptions( declaration );
closingBrace( declaration );
return declaration.toString();
}
private boolean specialNeeds(List<String> paramTypes, StringBuilder declaration) {
boolean unwrapped;
if ( !isJakartaKeyedSlice(containerType) ) {
unwrapped = handleSpecialParameters( paramTypes, declaration );
unwrapped = orderBy( declaration, unwrapped );
}
else {
unwrapped = !isUsingEntityManager();
}
private boolean specialNeeds(StringBuilder declaration) {
boolean unwrapped = !isUsingEntityManager();
// if ( isJakartaKeyedSlice(containerType) ) {
// unwrapped = !isUsingEntityManager();
// }
// else {
// unwrapped = orderBy( declaration, unwrapped );
// }
unwrapped = unwrapIfNecessary( declaration, containerType, unwrapped );
if ( isUpdate || containerType == null || !isQueryType(containerType)) {
declaration
.append("\n\t\t\t");
}
// if ( isUpdate || containerType == null || !isQueryType(containerType)) {
// declaration
// .append("\t\t\t");
// }
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 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 );
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(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 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(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;
// }
// }
@Override
void createQuery(StringBuilder declaration) {
@ -177,7 +178,7 @@ void createQuery(StringBuilder declaration) {
.append(annotationMetaEntity.importType(returnTypeName))
.append(".class");
}
declaration.append(")");
declaration.append(")\n");
}
private void castResult(StringBuilder declaration, StringBuilder returnType) {
@ -204,6 +205,7 @@ private void preamble(StringBuilder declaration, StringBuilder returnType, List<
private void execute(StringBuilder declaration, boolean unwrapped) {
if ( isUpdate ) {
declaration
.append("\t\t\t")
.append(".executeUpdate()");
if ( "boolean".equals(returnTypeName) ) {
declaration.append(" > 0");
@ -240,37 +242,22 @@ else if ( queryString.contains("?" + ordinal) ) {
}
}
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;
}
private static void setOrdinalParameter(StringBuilder declaration, int i, String paramName) {
declaration
.append("\n\t\t\t.setParameter(")
.append("\t\t\t.setParameter(")
.append(i)
.append(", ")
.append(paramName)
.append(")");
.append(")\n");
}
private static void setNamedParameter(StringBuilder declaration, String paramName) {
declaration
.append("\n\t\t\t.setParameter(\"")
.append("\t\t\t.setParameter(\"")
.append(paramName)
.append("\", ")
.append(paramName)
.append(")");
.append(")\n");
}
private StringBuilder returnType() {

View File

@ -124,4 +124,10 @@ public interface BookAuthorRepository {
@Query("from Book where title like :titlePattern")
KeysetAwarePage<Book> everyBook9(String titlePattern, PageRequest<Book> pageRequest);
@Find
Page<Book> booksByTitle1(String title, PageRequest<Book> pageRequest);
@Query("from Book where title like :titlePattern")
Slice<Book> booksByTitle2(String titlePattern, PageRequest<Book> pageRequest);
}