allow criteria-based @Find methods to specify Page and Order
This is not necessary for @Id or @NaturalId-based @Find methods, because they don't return multiple results.
This commit is contained in:
parent
1c15267d3a
commit
8794f86ad2
|
@ -10,6 +10,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
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.Page;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -159,4 +161,59 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
|
||||||
boolean isReactive() {
|
boolean isReactive() {
|
||||||
return Constants.MUTINY_SESSION.equals(sessionType);
|
return Constants.MUTINY_SESSION.equals(sessionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPage(StringBuilder declaration, String paramName) {
|
||||||
|
if ( isUsingEntityManager() ) {
|
||||||
|
declaration
|
||||||
|
.append("\n\t\t\t.setFirstResult(")
|
||||||
|
.append(paramName)
|
||||||
|
.append(".getFirstResult())")
|
||||||
|
.append("\n\t\t\t.setMaxResults(")
|
||||||
|
.append(paramName)
|
||||||
|
.append(".getMaxResults())");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
declaration
|
||||||
|
.append("\n\t\t\t.setPage(")
|
||||||
|
.append(paramName)
|
||||||
|
.append(")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean setOrder(StringBuilder declaration, boolean unwrapped, String paramName, String paramType) {
|
||||||
|
unwrapQuery( declaration, unwrapped );
|
||||||
|
if ( paramType.endsWith("...") ) {
|
||||||
|
declaration
|
||||||
|
.append("\n\t\t\t.setOrder(")
|
||||||
|
.append(annotationMetaEntity.importType(Constants.LIST))
|
||||||
|
.append(".of(")
|
||||||
|
.append(paramName)
|
||||||
|
.append("))");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
declaration
|
||||||
|
.append("\n\t\t\t.setOrder(")
|
||||||
|
.append(paramName)
|
||||||
|
.append(")");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unwrapQuery(StringBuilder declaration, boolean unwrapped) {
|
||||||
|
if ( !unwrapped ) {
|
||||||
|
declaration
|
||||||
|
.append("\n\t\t\t.unwrap(")
|
||||||
|
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
|
||||||
|
.append(".class)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isPageParam(String parameterType) {
|
||||||
|
return Page.class.getName().equals(parameterType);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isOrderParam(String parameterType) {
|
||||||
|
return parameterType.startsWith(Order.class.getName())
|
||||||
|
|| parameterType.startsWith(List.class.getName() + "<" + Order.class.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -573,7 +573,10 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isFinderParameterMappingToAttribute(VariableElement param) {
|
private static boolean isFinderParameterMappingToAttribute(VariableElement param) {
|
||||||
return !isSessionParameter( param.asType().toString() );
|
final String type = param.asType().toString();
|
||||||
|
return !isSessionParameter( type )
|
||||||
|
&& !isPageParam( type )
|
||||||
|
&& !isOrderParam( type );
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] sessionTypeFromParameters(List<String> paramNames, List<String> paramTypes) {
|
private String[] sessionTypeFromParameters(List<String> paramNames, List<String> paramTypes) {
|
||||||
|
|
|
@ -86,7 +86,9 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
for ( int i = 0; i < paramNames.size(); i ++ ) {
|
for ( int i = 0; i < paramNames.size(); i ++ ) {
|
||||||
final String paramName = paramNames.get(i);
|
final String paramName = paramNames.get(i);
|
||||||
final String paramType = paramTypes.get(i);
|
final String paramType = paramTypes.get(i);
|
||||||
if ( !isSessionParameter(paramType) ) {
|
if ( !isSessionParameter(paramType)
|
||||||
|
&& !isPageParam(paramType)
|
||||||
|
&& !isOrderParam(paramType) ) {
|
||||||
if ( first ) {
|
if ( first ) {
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
@ -94,27 +96,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
declaration
|
declaration
|
||||||
.append(", ");
|
.append(", ");
|
||||||
}
|
}
|
||||||
declaration
|
parameter( declaration, i, paramName, paramType );
|
||||||
.append("\n\t\t\t");
|
|
||||||
if ( isNullable(i) && !isPrimitive(paramType) ) {
|
|
||||||
declaration
|
|
||||||
.append(paramName)
|
|
||||||
.append("==null")
|
|
||||||
.append("\n\t\t\t\t? ")
|
|
||||||
.append("entity");
|
|
||||||
path( declaration, paramName );
|
|
||||||
declaration
|
|
||||||
.append(".isNull()")
|
|
||||||
.append("\n\t\t\t\t: ");
|
|
||||||
}
|
|
||||||
declaration
|
|
||||||
.append("builder.equal(entity");
|
|
||||||
path( declaration, paramName );
|
|
||||||
declaration
|
|
||||||
.append(", ")
|
|
||||||
//TODO: only safe if we are binding literals as parameters!!!
|
|
||||||
.append(paramName)
|
|
||||||
.append(')');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declaration
|
declaration
|
||||||
|
@ -122,11 +104,12 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
.append("\n\treturn ")
|
.append("\n\treturn ")
|
||||||
.append(sessionName)
|
.append(sessionName)
|
||||||
.append(".createQuery(query)");
|
.append(".createQuery(query)");
|
||||||
|
final boolean hasOrderParameter = paramTypes.stream().anyMatch(AbstractQueryMethod::isOrderParam);
|
||||||
final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
|
final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
|
||||||
final boolean hasNativeReturnType =
|
final boolean hasNativeReturnType =
|
||||||
containerType != null && containerType.startsWith("org.hibernate");
|
containerType != null && containerType.startsWith("org.hibernate");
|
||||||
final boolean unwrap =
|
final boolean unwrap =
|
||||||
( hasEnabledFetchProfiles || hasNativeReturnType )
|
( hasOrderParameter || hasEnabledFetchProfiles || hasNativeReturnType )
|
||||||
&& isUsingEntityManager();
|
&& isUsingEntityManager();
|
||||||
if ( unwrap ) {
|
if ( unwrap ) {
|
||||||
declaration
|
declaration
|
||||||
|
@ -134,16 +117,26 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
|
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
|
||||||
.append(".class)");
|
.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 );
|
||||||
|
}
|
||||||
|
else if ( isOrderParam(paramType) ) {
|
||||||
|
setOrder( declaration, true, paramName, paramType );
|
||||||
|
}
|
||||||
|
}
|
||||||
enableFetchProfile( declaration );
|
enableFetchProfile( declaration );
|
||||||
if ( containerType == null) {
|
if ( containerType == null) {
|
||||||
if ( unwrap || hasEnabledFetchProfiles) {
|
if ( unwrap || hasEnabledFetchProfiles ) {
|
||||||
declaration.append("\n\t\t\t");
|
declaration.append("\n\t\t\t");
|
||||||
}
|
}
|
||||||
declaration
|
declaration
|
||||||
.append(".getSingleResult()");
|
.append(".getSingleResult()");
|
||||||
}
|
}
|
||||||
else if ( containerType.equals(Constants.LIST) ) {
|
else if ( containerType.equals(Constants.LIST) ) {
|
||||||
if ( unwrap || hasEnabledFetchProfiles ) {
|
if ( unwrap || hasOrderParameter || hasEnabledFetchProfiles ) {
|
||||||
declaration.append("\n\t\t\t");
|
declaration.append("\n\t\t\t");
|
||||||
}
|
}
|
||||||
declaration
|
declaration
|
||||||
|
@ -154,6 +147,30 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
||||||
return declaration.toString();
|
return declaration.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void parameter(StringBuilder declaration, int i, String paramName, String paramType) {
|
||||||
|
declaration
|
||||||
|
.append("\n\t\t\t");
|
||||||
|
if ( isNullable(i) && !isPrimitive(paramType) ) {
|
||||||
|
declaration
|
||||||
|
.append(paramName)
|
||||||
|
.append("==null")
|
||||||
|
.append("\n\t\t\t\t? ")
|
||||||
|
.append("entity");
|
||||||
|
path( declaration, paramName );
|
||||||
|
declaration
|
||||||
|
.append(".isNull()")
|
||||||
|
.append("\n\t\t\t\t: ");
|
||||||
|
}
|
||||||
|
declaration
|
||||||
|
.append("builder.equal(entity");
|
||||||
|
path( declaration, paramName );
|
||||||
|
declaration
|
||||||
|
.append(", ")
|
||||||
|
//TODO: only safe if we are binding literals as parameters!!!
|
||||||
|
.append(paramName)
|
||||||
|
.append(')');
|
||||||
|
}
|
||||||
|
|
||||||
private void path(StringBuilder declaration, String paramName) {
|
private void path(StringBuilder declaration, String paramName) {
|
||||||
final StringTokenizer tokens = new StringTokenizer(paramName, "$");
|
final StringTokenizer tokens = new StringTokenizer(paramName, "$");
|
||||||
String typeName = entity;
|
String typeName = entity;
|
||||||
|
|
|
@ -183,43 +183,6 @@ public class QueryMethod extends AbstractQueryMethod {
|
||||||
.append(")");
|
.append(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPage(StringBuilder declaration, String paramName) {
|
|
||||||
if ( isUsingEntityManager() ) {
|
|
||||||
declaration
|
|
||||||
.append("\n\t\t\t.setFirstResult(")
|
|
||||||
.append(paramName)
|
|
||||||
.append(".getFirstResult())")
|
|
||||||
.append("\n\t\t\t.setMaxResults(")
|
|
||||||
.append(paramName)
|
|
||||||
.append(".getMaxResults())");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
declaration
|
|
||||||
.append("\n\t\t\t.setPage(")
|
|
||||||
.append(paramName)
|
|
||||||
.append(")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean setOrder(StringBuilder declaration, boolean unwrapped, String paramName, String paramType) {
|
|
||||||
unwrap( declaration, unwrapped );
|
|
||||||
if ( paramType.endsWith("...") ) {
|
|
||||||
declaration
|
|
||||||
.append("\n\t\t\t.setOrder(")
|
|
||||||
.append(annotationMetaEntity.importType(Constants.LIST))
|
|
||||||
.append(".of(")
|
|
||||||
.append(paramName)
|
|
||||||
.append("))");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
declaration
|
|
||||||
.append("\n\t\t\t.setOrder(")
|
|
||||||
.append(paramName)
|
|
||||||
.append(")");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private StringBuilder returnType() {
|
private StringBuilder returnType() {
|
||||||
StringBuilder type = new StringBuilder();
|
StringBuilder type = new StringBuilder();
|
||||||
boolean returnsUni = isReactive()
|
boolean returnsUni = isReactive()
|
||||||
|
@ -283,24 +246,6 @@ public class QueryMethod extends AbstractQueryMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isPageParam(String parameterType) {
|
|
||||||
return Page.class.getName().equals(parameterType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isOrderParam(String parameterType) {
|
|
||||||
return parameterType.startsWith(Order.class.getName())
|
|
||||||
|| parameterType.startsWith(List.class.getName() + "<" + Order.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unwrap(StringBuilder declaration, boolean unwrapped) {
|
|
||||||
if ( !unwrapped ) {
|
|
||||||
declaration
|
|
||||||
.append("\n\t\t\t.unwrap(")
|
|
||||||
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
|
|
||||||
.append(".class)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAttributeNameDeclarationString() {
|
public String getAttributeNameDeclarationString() {
|
||||||
return new StringBuilder()
|
return new StringBuilder()
|
||||||
|
|
|
@ -5,6 +5,8 @@ import jakarta.persistence.TypedQuery;
|
||||||
import org.hibernate.annotations.processing.Find;
|
import org.hibernate.annotations.processing.Find;
|
||||||
import org.hibernate.annotations.processing.HQL;
|
import org.hibernate.annotations.processing.HQL;
|
||||||
import org.hibernate.annotations.processing.SQL;
|
import org.hibernate.annotations.processing.SQL;
|
||||||
|
import org.hibernate.query.Order;
|
||||||
|
import org.hibernate.query.Page;
|
||||||
import org.hibernate.query.SelectionQuery;
|
import org.hibernate.query.SelectionQuery;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -34,6 +36,9 @@ public interface Dao {
|
||||||
@Find(enabledFetchProfiles="Hello")
|
@Find(enabledFetchProfiles="Hello")
|
||||||
List<Book> getBooksFetching(String title);
|
List<Book> getBooksFetching(String title);
|
||||||
|
|
||||||
|
@Find
|
||||||
|
List<Book> getBooks(String title, Page page, Order<Book> order);
|
||||||
|
|
||||||
@Find
|
@Find
|
||||||
SelectionQuery<Book> createBooksSelectionQuery(String title);
|
SelectionQuery<Book> createBooksSelectionQuery(String title);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue