Skip to content

Commit

Permalink
clarify use of Order and Page with @find
Browse files Browse the repository at this point in the history
[It's allowed!]
  • Loading branch information
gavinking committed Feb 2, 2024
1 parent 39457c5 commit d96b5df
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
18 changes: 16 additions & 2 deletions documentation/src/main/asciidoc/introduction/Generator.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ This lets us declare which associations of `Book` should be pre-fetched by annot
[[paging-and-ordering]]
=== Paging and ordering

Optionally, a query method may have additional "magic" parameters which do not map to query parameters:
Optionally, a query method--or a finder method which returns multiple results--may have additional "magic" parameters which do not map to query parameters:

[cols="19,~,32m"]
|===
Expand All @@ -537,7 +537,8 @@ Thus, if we redefine our earlier query method as follows:
----
interface Queries {
@HQL("from Book where title like :title and type = :type")
List<Book> findBooksByTitleAndType(String title, Page page, Order<? super Book>... order);
List<Book> findBooksByTitleAndType(String title, Type type,
Page page, Order<? super Book>... order);
}
----

Expand All @@ -550,6 +551,19 @@ List<Book> books =
Page.page(RESULTS_PER_PAGE, page), Order.asc(Book_.isbn));
----

Alternatively, we could have written this query method as a finder method:

[source,java]
----
interface Queries {
@Find
List<Book> getBooksByTitle(String title, Type type,
Page page, Order<? super Book>... order);
}
----

This gives some dynamic control over query execution, but what if would like direct control over the `Query` object?
Well, let's talk about the return type.

[[return-types]]
=== Query and finder method return types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
* or one of the following types:
* <ul>
* <li>{@link java.util.List java.util.List&lt;E&gt;},
* <li>{@code io.smallrye.mutiny.Uni&lt;E&gt;}, when used with Hibernate Reactive,
* <li>{@code io.smallrye.mutiny.Uni<E>}, when used with Hibernate Reactive,
* <li>{@link org.hibernate.query.Query org.hibernate.query.Query&lt;E&gt;},
* <li>{@link org.hibernate.query.SelectionQuery org.hibernate.query.SelectionQuery&lt;E&gt;},
* <li>{@link jakarta.persistence.Query jakarta.persistence.Query&lt;E&gt;}, or
Expand Down Expand Up @@ -123,7 +123,16 @@
* <p>
* As an exception, the method may have at most one parameter of
* type {@code EntityManager}, {@code Session},
* {@code StatelessSession}, or {@code Mutiny.Session}.
* {@code StatelessSession}, or {@code Mutiny.Session}. Furthermore,
* if the finder method returns multiple results, that is, if its
* return type is {@code List}, then it may also have:
* <ul>
* <li>a parameter with type {@code Page}, and/or
* <li>a parameter with type {@code Order<? super E>},
* {@code List<Order<? super E>>}, or {@code Order<? super E>...}
* (varargs) where {@code E} is the entity type returned by the
* query.
* </ul>
*
* @see HQL
* @see SQL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,15 @@ private void addFinderMethod(
createCriteriaFinder( method, returnType, containerType, entity );
}
else {
for ( VariableElement parameter : method.getParameters() ) {
final String type = parameter.asType().toString();
if ( isPageParam(type) ) {
context.message( parameter, "pagination would have no effect", Diagnostic.Kind.ERROR);
}
else if ( isOrderParam(type) ) {
context.message( parameter, "ordering would have no effect", Diagnostic.Kind.ERROR);
}
}
final long parameterCount =
method.getParameters().stream()
.filter(AnnotationMetaEntity::isFinderParameterMappingToAttribute)
Expand All @@ -570,8 +579,8 @@ private void addFinderMethod(
private void createCriteriaFinder(
ExecutableElement method, TypeMirror returnType, @Nullable TypeElement containerType, TypeElement entity) {
final String methodName = method.getSimpleName().toString();
final List<String> paramNames = parameterNames(method);
final List<String> paramTypes = parameterTypes(method);
final List<String> paramNames = parameterNames( method );
final List<String> paramTypes = parameterTypes( method );
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
final String methodKey = methodName + paramTypes;
for ( VariableElement param : method.getParameters() ) {
Expand Down Expand Up @@ -683,8 +692,8 @@ private void createSingleParameterFinder(ExecutableElement method, TypeMirror re
method.getParameters().stream()
.filter(AnnotationMetaEntity::isFinderParameterMappingToAttribute)
.findFirst().orElseThrow();
final List<String> paramNames = parameterNames(method);
final List<String> paramTypes = parameterTypes(method);
final List<String> paramNames = parameterNames( method );
final List<String> paramTypes = parameterTypes( method );
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
final FieldType fieldType = validateFinderParameter( entity, parameter );
if ( fieldType != null ) {
Expand Down

0 comments on commit d96b5df

Please sign in to comment.