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.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
import org.hibernate.query.Order;
|
||||
import org.hibernate.query.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -159,4 +161,59 @@ public abstract class AbstractQueryMethod implements MetaAttribute {
|
|||
boolean isReactive() {
|
||||
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) {
|
||||
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) {
|
||||
|
|
|
@ -86,7 +86,9 @@ 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) ) {
|
||||
if ( !isSessionParameter(paramType)
|
||||
&& !isPageParam(paramType)
|
||||
&& !isOrderParam(paramType) ) {
|
||||
if ( first ) {
|
||||
first = false;
|
||||
}
|
||||
|
@ -94,27 +96,7 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
declaration
|
||||
.append(", ");
|
||||
}
|
||||
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(')');
|
||||
parameter( declaration, i, paramName, paramType );
|
||||
}
|
||||
}
|
||||
declaration
|
||||
|
@ -122,11 +104,12 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
.append("\n\treturn ")
|
||||
.append(sessionName)
|
||||
.append(".createQuery(query)");
|
||||
final boolean hasOrderParameter = paramTypes.stream().anyMatch(AbstractQueryMethod::isOrderParam);
|
||||
final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
|
||||
final boolean hasNativeReturnType =
|
||||
containerType != null && containerType.startsWith("org.hibernate");
|
||||
final boolean unwrap =
|
||||
( hasEnabledFetchProfiles || hasNativeReturnType )
|
||||
( hasOrderParameter || hasEnabledFetchProfiles || hasNativeReturnType )
|
||||
&& isUsingEntityManager();
|
||||
if ( unwrap ) {
|
||||
declaration
|
||||
|
@ -134,16 +117,26 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
.append(annotationMetaEntity.importType(Constants.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 );
|
||||
}
|
||||
else if ( isOrderParam(paramType) ) {
|
||||
setOrder( declaration, true, paramName, paramType );
|
||||
}
|
||||
}
|
||||
enableFetchProfile( declaration );
|
||||
if ( containerType == null) {
|
||||
if ( unwrap || hasEnabledFetchProfiles) {
|
||||
if ( unwrap || hasEnabledFetchProfiles ) {
|
||||
declaration.append("\n\t\t\t");
|
||||
}
|
||||
declaration
|
||||
.append(".getSingleResult()");
|
||||
}
|
||||
else if ( containerType.equals(Constants.LIST) ) {
|
||||
if ( unwrap || hasEnabledFetchProfiles ) {
|
||||
if ( unwrap || hasOrderParameter || hasEnabledFetchProfiles ) {
|
||||
declaration.append("\n\t\t\t");
|
||||
}
|
||||
declaration
|
||||
|
@ -154,6 +147,30 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
|
|||
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) {
|
||||
final StringTokenizer tokens = new StringTokenizer(paramName, "$");
|
||||
String typeName = entity;
|
||||
|
|
|
@ -183,43 +183,6 @@ public class QueryMethod extends AbstractQueryMethod {
|
|||
.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() {
|
||||
StringBuilder type = new StringBuilder();
|
||||
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
|
||||
public String getAttributeNameDeclarationString() {
|
||||
return new StringBuilder()
|
||||
|
|
|
@ -5,6 +5,8 @@ import jakarta.persistence.TypedQuery;
|
|||
import org.hibernate.annotations.processing.Find;
|
||||
import org.hibernate.annotations.processing.HQL;
|
||||
import org.hibernate.annotations.processing.SQL;
|
||||
import org.hibernate.query.Order;
|
||||
import org.hibernate.query.Page;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -34,6 +36,9 @@ public interface Dao {
|
|||
@Find(enabledFetchProfiles="Hello")
|
||||
List<Book> getBooksFetching(String title);
|
||||
|
||||
@Find
|
||||
List<Book> getBooks(String title, Page page, Order<Book> order);
|
||||
|
||||
@Find
|
||||
SelectionQuery<Book> createBooksSelectionQuery(String title);
|
||||
|
||||
|
|
Loading…
Reference in New Issue