Skip to content

Commit d96b5df

Browse files
committedFeb 2, 2024
clarify use of Order and Page with @find
[It's allowed!]
1 parent 39457c5 commit d96b5df

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed
 

‎documentation/src/main/asciidoc/introduction/Generator.adoc

+16-2
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ This lets us declare which associations of `Book` should be pre-fetched by annot
516516
[[paging-and-ordering]]
517517
=== Paging and ordering
518518

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

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

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

554+
Alternatively, we could have written this query method as a finder method:
555+
556+
[source,java]
557+
----
558+
interface Queries {
559+
@Find
560+
List<Book> getBooksByTitle(String title, Type type,
561+
Page page, Order<? super Book>... order);
562+
}
563+
----
564+
565+
This gives some dynamic control over query execution, but what if would like direct control over the `Query` object?
566+
Well, let's talk about the return type.
553567

554568
[[return-types]]
555569
=== Query and finder method return types

‎hibernate-core/src/main/java/org/hibernate/annotations/processing/Find.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
* or one of the following types:
9292
* <ul>
9393
* <li>{@link java.util.List java.util.List&lt;E&gt;},
94-
* <li>{@code io.smallrye.mutiny.Uni&lt;E&gt;}, when used with Hibernate Reactive,
94+
* <li>{@code io.smallrye.mutiny.Uni<E>}, when used with Hibernate Reactive,
9595
* <li>{@link org.hibernate.query.Query org.hibernate.query.Query&lt;E&gt;},
9696
* <li>{@link org.hibernate.query.SelectionQuery org.hibernate.query.SelectionQuery&lt;E&gt;},
9797
* <li>{@link jakarta.persistence.Query jakarta.persistence.Query&lt;E&gt;}, or
@@ -123,7 +123,16 @@
123123
* <p>
124124
* As an exception, the method may have at most one parameter of
125125
* type {@code EntityManager}, {@code Session},
126-
* {@code StatelessSession}, or {@code Mutiny.Session}.
126+
* {@code StatelessSession}, or {@code Mutiny.Session}. Furthermore,
127+
* if the finder method returns multiple results, that is, if its
128+
* return type is {@code List}, then it may also have:
129+
* <ul>
130+
* <li>a parameter with type {@code Page}, and/or
131+
* <li>a parameter with type {@code Order<? super E>},
132+
* {@code List<Order<? super E>>}, or {@code Order<? super E>...}
133+
* (varargs) where {@code E} is the entity type returned by the
134+
* query.
135+
* </ul>
127136
*
128137
* @see HQL
129138
* @see SQL

‎tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java

+13-4
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,15 @@ private void addFinderMethod(
545545
createCriteriaFinder( method, returnType, containerType, entity );
546546
}
547547
else {
548+
for ( VariableElement parameter : method.getParameters() ) {
549+
final String type = parameter.asType().toString();
550+
if ( isPageParam(type) ) {
551+
context.message( parameter, "pagination would have no effect", Diagnostic.Kind.ERROR);
552+
}
553+
else if ( isOrderParam(type) ) {
554+
context.message( parameter, "ordering would have no effect", Diagnostic.Kind.ERROR);
555+
}
556+
}
548557
final long parameterCount =
549558
method.getParameters().stream()
550559
.filter(AnnotationMetaEntity::isFinderParameterMappingToAttribute)
@@ -570,8 +579,8 @@ private void addFinderMethod(
570579
private void createCriteriaFinder(
571580
ExecutableElement method, TypeMirror returnType, @Nullable TypeElement containerType, TypeElement entity) {
572581
final String methodName = method.getSimpleName().toString();
573-
final List<String> paramNames = parameterNames(method);
574-
final List<String> paramTypes = parameterTypes(method);
582+
final List<String> paramNames = parameterNames( method );
583+
final List<String> paramTypes = parameterTypes( method );
575584
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
576585
final String methodKey = methodName + paramTypes;
577586
for ( VariableElement param : method.getParameters() ) {
@@ -683,8 +692,8 @@ private void createSingleParameterFinder(ExecutableElement method, TypeMirror re
683692
method.getParameters().stream()
684693
.filter(AnnotationMetaEntity::isFinderParameterMappingToAttribute)
685694
.findFirst().orElseThrow();
686-
final List<String> paramNames = parameterNames(method);
687-
final List<String> paramTypes = parameterTypes(method);
695+
final List<String> paramNames = parameterNames( method );
696+
final List<String> paramTypes = parameterTypes( method );
688697
final String[] sessionType = sessionTypeFromParameters( paramNames, paramTypes );
689698
final FieldType fieldType = validateFinderParameter( entity, parameter );
690699
if ( fieldType != null ) {

0 commit comments

Comments
 (0)
Please sign in to comment.