You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In Hibernate 7, we can often use <<restrictions-and-ordering,`Restriction`>> instead.
927
929
====
928
930
929
931
Do you find some of the code above a bit too verbose?
@@ -1034,8 +1036,59 @@ List<Book> books =
1034
1036
You can call stored procedures using `createStoredProcedureQuery()` or `createStoredProcedureCall()`.
1035
1037
====
1036
1038
1039
+
[[restrictions-and-ordering]]
1040
+
=== Restrictions and ordering
1041
+
1042
+
We've already seen how the JPA <<criteria-queries,Criteria Query API>> can be used to construct a query completely programmatically.
1043
+
The Criteria API is powerful, but for the most common scenarios it's at least arguably overkill.
1044
+
The <<criteria-definition,`CriteriaDefinition`>> class helps a bit, but it doesn't completely eliminate the verbosity of programmatic query definition.
1045
+
1046
+
In Hibernate 7, there's a new option, a very ergonomic API for programmatically adding restrictions or ordering to an existing query before executing it.
1047
+
(Actually, the ordering part of this was introduced in Hibernate 6.5.)
1048
+
This new API:
1049
+
1050
+
- isn't part of the Criteria Query API, and so we don't need a `CriteriaQuery` object to make use of it,
1051
+
- works with both HQL and Criteria queries, and even with <<named-queries,named HQL queries>>, and
1052
+
- is optimized for the case of a query which returns its single root entity.
1053
+
1054
+
[source,java]
1055
+
----
1056
+
var query = session.createSelectionQuery("from Book where year(publicationDate) > 2000", Book.class);
- The link:{doc-javadoc-url}org/hibernate/query/Restriction.html[`Restriction`] interface has static methods for constructing a variety of different kinds of restriction in a completely typesafe way.
1071
+
- Similarly, the link:{doc-javadoc-url}org/hibernate/query/Order.html[`Order`] class has a variety of static methods for constructing different kinds of ordering criteria.
1072
+
1073
+
We need the following methods of `SelectionQuery`:
1074
+
1075
+
.Methods for query restriction and ordering
1076
+
[%breakable,cols="30,~,^15"]
1077
+
|===
1078
+
| Method name | Purpose | JPA-standard
1079
+
1080
+
| `addRestriction()` | Add a restriction on the query results | ✖
1081
+
| `setOrder()` | Specify how the query results should be ordered | ✖
1082
+
|===
1083
+
1084
+
Unfortunately, `Restriction` and `Order` can't be used with JPA's `TypedQuery` interface, and JPA has no built-in alternative, so if we're using `EntityManager`, we need to call `unwrap()` to obtain a `SelectionQuery`.
1085
+
1086
+
Alternatively, `Restriction` and `Order` can be used with <<paging-and-ordering,generated query or finder methods>>, and even with link:{doc-data-repositories-url}[Jakarta Data repositories].
1087
+
1088
+
Programmatic restrictions, and especially programmatic ordering, are often used together with pagination.
1089
+
1037
1090
[[pagination]]
1038
-
=== Limits, pagination, and ordering
1091
+
=== Limitsand pagination
1039
1092
1040
1093
If a query might return more results than we can handle at one time, we may specify:
.Methods for query limits, pagination, and ordering
1156
+
[%breakable,cols="30,~,^15"]
1157
+
|===
1158
+
| Method name | Purpose | JPA-standard
1159
+
1160
+
| `setMaxResults()` | Set a limit on the number of results returned by a query | ✔
1161
+
| `setFirstResult()` | Set an offset on the results returned by a query | ✔
1162
+
| `setPage()` | Set the limit and offset by specifying a `Page` object | ✖
1163
+
| `getResultCount()` | Determine how many results the query would return in the absence of any limit or offset | ✖
1164
+
|===
1165
+
1103
1166
It's quite common for pagination to be combined with the need to order query results by a field that's determined at runtime.
1104
-
So, as an alternative to the HQL `order by` clause, `SelectionQuery` offers the ability to specify that the query results should be ordered by one or more fields of the entity type returned by the query:
1167
+
The `Order` class we just met <<restrictions-and-ordering,above>> provides the ability to specify that the query results should be ordered by one or more fields of the entity type returned by the query:
1105
1168
1169
+
[[query-order-example]]
1106
1170
[source,java]
1107
1171
----
1108
1172
List<Book> books =
@@ -1113,20 +1177,6 @@ List<Book> books =
1113
1177
.getResultList();
1114
1178
----
1115
1179
1116
-
Unfortunately, there's no way to do this using JPA's `TypedQuery` interface.
1117
-
1118
-
.Methods for query limits, pagination, and ordering
1119
-
[%breakable,cols="30,~,^15"]
1120
-
|===
1121
-
| Method name | Purpose | JPA-standard
1122
-
1123
-
| `setMaxResults()` | Set a limit on the number of results returned by a query | ✔
1124
-
| `setFirstResult()` | Set an offset on the results returned by a query | ✔
1125
-
| `setPage()` | Set the limit and offset by specifying a `Page` object | ✖
1126
-
| `setOrder()` | Specify how the query results should be ordered | ✖
1127
-
| `getResultCount()` | Determine how many results the query would return in the absence of any limit or offset | ✖
1128
-
|===
1129
-
1130
1180
The approach to pagination we've just seen is sometimes called _offset-based pagination_.
1131
1181
Since Hibernate 6.5, there's an alternative approach, which offers some advantages, though it's a little more difficult to use.
Copy file name to clipboardExpand all lines: documentation/src/main/asciidoc/introduction/Processor.adoc
+43-3Lines changed: 43 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -555,6 +555,24 @@ The `@Pattern` annotation may be applied to a parameter of type `String`, indica
555
555
List<Book> getBooksByTitle(@Pattern String title, Type type);
556
556
----
557
557
558
+
Even better, a parameter may be of type `Range<T>`, where `T` is the type of the matching field.
559
+
560
+
[source,java]
561
+
----
562
+
@Find
563
+
List<Book> getBooksByTitle(Range<String> title, Type type);
564
+
----
565
+
566
+
The link:{doc-javadoc-url}org/hibernate/query/range/Range.html[`Range`] interface has a variety of `static` methods the caller may use to construct different kinds of ranges.
567
+
For example, `Range.pattern()` constructs a `Range` representing a pattern.
568
+
569
+
[source,java]
570
+
----
571
+
List<Book> books =
572
+
// returns books with titles beginning with "hibernate"
A finder method may specify <<fetch-profiles,fetch profiles>>, for example:
559
577
560
578
[source,java]
@@ -588,7 +606,7 @@ This lets us declare which associations of `Book` should be pre-fetched by annot
588
606
// ----
589
607
590
608
[[paging-and-ordering]]
591
-
=== Pagingand ordering
609
+
=== Paging, ordering, and restrictions
592
610
593
611
Optionally, a query method--or a finder method which returns multiple results--may have additional "magic" parameters which do not map to query parameters:
594
612
@@ -603,6 +621,7 @@ Optionally, a query method--or a finder method which returns multiple results--m
603
621
| `Order<Object[]>` | Specifies a column to order by, if the query returns a projection list | Order.asc(1)
604
622
| `List<Object[]>` +
605
623
(or varargs) | Specifies columns to order by, if the query returns a projection list | List.of(Order.asc(1), Order.desc(2))
624
+
| `Restriction<? super E>` | Specifies a restriction used to filter query results | Restriction.startsWith("Hibernate")
606
625
|===
607
626
608
627
Thus, if we redefine our earlier query method as follows:
@@ -636,8 +655,28 @@ interface Queries {
636
655
}
637
656
----
638
657
639
-
This gives some dynamic control over query execution, but what if we would like direct control over the `Query` object?
640
-
Well, let's talk about the return type.
658
+
Similarly, we may define a query method which accepts an arbitrary ``Restriction``:
659
+
660
+
[source,java]
661
+
----
662
+
interface Queries {
663
+
@Find
664
+
List<Book> findBooks(Restriction<? super Book> restriction, Order<? super Book>... order);
665
+
}
666
+
----
667
+
668
+
As we <<restrictions-and-ordering,saw earlier>>, the `Restriction` interface has a variety of `static` methods for constructing restrictions.
669
+
670
+
[source,java]
671
+
----
672
+
List<Book> books =
673
+
// returns books with titles beginning with "hibernate", sorted by title
0 commit comments