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
Copy file name to clipboardExpand all lines: documentation/src/main/asciidoc/repositories/Pagination.adoc
+66-4Lines changed: 66 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,7 @@ An <<find-method,automatic>> or <<query-method,annotated>> query method may have
8
8
9
9
Before we see this, let's see how we can refer to a field of an entity in a completely typesafe way.
10
10
11
+
[[data-static-metamodel]]
11
12
=== The static metamodel
12
13
13
14
You might already be familiar with the Jakarta Persistence static metamodel.
@@ -59,6 +60,7 @@ This example looks superficially more typesafe.
59
60
But since Hibernate Data Repositories already validates the content of the `@OrderBy` annotation at compile time, it's not really better.
60
61
====
61
62
63
+
[[dynamic-sorting]]
62
64
=== Dynamic sorting
63
65
64
66
Dynamic sorting criteria are expressed using the types `Sort` and `Order`:
@@ -100,7 +102,7 @@ The method might now be called like this:
100
102
var books =
101
103
library.books(pattern, year,
102
104
Order.of(_Book.title.ascIgnoreCase(),
103
-
_Book.isbn.asc());
105
+
_Book.isbn.asc()));
104
106
----
105
107
106
108
Dynamic sorting criteria may be combined with static criteria.
@@ -115,6 +117,7 @@ List<Book> books(@Pattern String title, Year yearPublished,
115
117
116
118
We're not convinced this is very useful in practice.
117
119
120
+
[[limits]]
118
121
=== Limits
119
122
120
123
A `Limit` is the simplest way to express a subrange of query results.
@@ -141,6 +144,7 @@ var books =
141
144
142
145
A more sophisticated approach is provided by `PageRequest`.
143
146
147
+
[[offset-based-pagination]]
144
148
=== Offset-based pagination
145
149
146
150
A `PageRequest` is superficially similar to a `Limit`, except that it's specified in terms of:
@@ -218,6 +222,7 @@ We'll refer to this as _offset-based pagination_.
218
222
A problem with this approach is that it's quite vulnerable to missed or duplicate results when the database is modified between page requests.
219
223
Therefore, Jakarta Data offers an alternative solution, which we'll call _key-based pagination_.
220
224
225
+
[[key-based-pagination]]
221
226
=== Key-based pagination
222
227
223
228
In key-based pagination, the query results must be totally ordered by a unique key of the result set.
@@ -241,7 +246,7 @@ The difference is that we must declare our repository method to return `Cursored
241
246
@OrderBy("title")
242
247
@OrderBy("isbn")
243
248
CursoredPage<Book> books(@Pattern String title, Year yearPublished,
244
-
PageRequest pageRequest);
249
+
PageRequest pageRequest);
245
250
----
246
251
247
252
On the other hand, with key-based pagination, Hibernate must do some work under the covers rewriting our query.
@@ -258,6 +263,63 @@ Direct API support for key-based pagination originated in the work of Hibernate
258
263
It was adopted from there by the Jakarta Data specification, and is now even available in Hibernate ORM via the link:{doc-javadoc-url}org/hibernate/query/KeyedPage.html[`KeyedPage`]/link:{doc-javadoc-url}org/hibernate/query/KeyedResultList.html[`KeyedResultList`] API.
259
264
****
260
265
266
+
[[dynamic-restrictions]]
267
+
=== Dynamic restrictions
268
+
269
+
Jakarta Data 1.0 does not include an API for programmatically specifying restrictions, but for now we may use the native link:{doc-javadoc-url}org/hibernate/query/restriction/Restriction.html[`Restriction`] API in Hibernate 7.
270
+
271
+
[NOTE]
272
+
====
273
+
Restrictions will be standardized by Jakarta Data 1.1.
274
+
====
275
+
276
+
Hibernate, an atomic `Restriction` is formed from:
277
+
278
+
- a reference to a JPA `SingularAttribute`, usually obtained via the _Jakarta Persistence_ (not Jakarta Data) static metamodel, together with
279
+
- a `Range` of allowed values for that attribute.
280
+
281
+
A query method may have a parameter of type `Restriction`, for example:
Notice the mix of metamodels here: `Book_` is the Persistence metamodel, and `_Book` is the Data metamodel.
301
+
302
+
It's even possible to directly use a link:{doc-javadoc-url}org/hibernate/query/range/Range.html[`Range`] to restrict a given property or field of an entity:
There are various kinds of `Range`, including lists, patterns, and intervals:
312
+
313
+
[source,java]
314
+
----
315
+
var books =
316
+
library.books(Range.prefix("Hibernate"),
317
+
Range.closed(Year.of(2000), Year.of(2009)),
318
+
Order.of(_Book.title.ascIgnoreCase(),
319
+
_Book.isbn.asc()));
320
+
----
321
+
322
+
[[advanced-query-control]]
261
323
=== Advanced control over querying
262
324
263
325
For more advanced usage, an automatic or annotated query method may be declared to return `jakarta.persistence.Query`, `jakarta.persistence.TypedQuery`, link:{doc-javadoc-url}org/hibernate/query/Query.html[`org.hibernate.query.Query`], or link:{doc-javadoc-url}org/hibernate/query/SelectionQuery.html[`org.hibernate.query.SelectionQuery`].
@@ -269,11 +331,11 @@ SelectionQuery<Book> booksQuery(@Pattern String title, Year yearPublished);
269
331
270
332
default List<Book> booksQuery(String title, Year yearPublished) {
271
333
return books(title, yearPublished)
272
-
.enableFetchProfile(_Book.PROFILE_WITH_AUTHORS);
334
+
.enableFetchProfile(_Book.PROFILE_WITH_AUTHORS)
273
335
.setReadOnly(true)
274
336
.setTimeout(QUERY_TIMEOUT)
275
337
.getResultList();
276
338
}
277
339
----
278
340
279
-
This allows for direct control over query execution, without loss of typesafety.
341
+
This allows for direct control over query execution, without loss of type safety.
Copy file name to clipboardExpand all lines: documentation/src/main/asciidoc/repositories/Repositories.adoc
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -131,6 +131,7 @@ interface Library {
131
131
132
132
This is our first example of a repository.
133
133
134
+
[[repository-interfaces]]
134
135
=== Repository interfaces
135
136
136
137
A _repository interface_ is an interface written by you, the application programmer, and annotated `@Repository`.
@@ -165,6 +166,7 @@ We'll discuss each of these kinds of method soon.
165
166
But first we need to ask a more basic question: how are persistence operations organized into repositories, and how do repository interfaces relate to entity types?
166
167
The--perhaps surprising--answer is: it's completely up to you.
167
168
169
+
[[organizing-repository-operations]]
168
170
=== Organizing persistence operations
169
171
170
172
Jakarta Data lets you freely assign persistence operations to repositories according to your own preference.
Unfortunately, native SQL queries cannot be validated at compile time, so if there's anything wrong with our SQL, we won't find out until we run our program.
538
540
541
+
[[by-and-param]]
539
542
=== `@By` and `@Param`
540
543
541
544
Query methods match method parameters to entity fields or query parameters by name.
0 commit comments