Skip to content

Commit 224b579

Browse files
committed
HHH-16383 - NaturalIdClass
1 parent 19dbfd4 commit 224b579

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

documentation/src/main/asciidoc/introduction/Entities.adoc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,20 @@ Hibernate automatically generates a `UNIQUE` constraint on the columns mapped by
526526
Consider using the natural id attributes to implement <<equals-and-hash>>.
527527
====
528528

529+
In cases where the natural id is defined by multiple attributes, Hibernate also offers the link:{doc-javadoc-url}org/hibernate/annotations/NaturalIdClass.html[`@NaturalIdClass`] annotation which acts similarly to the Jakarta Persistence `@IdClass` annotation for <<load-by-natural-id,find operations>> -
530+
531+
[source,java]
532+
----
533+
record BookKey(String isbn, int printing) {}
534+
535+
@Entity
536+
@NaturalIdClass(BookKey.class)
537+
class Book {
538+
...
539+
}
540+
----
541+
542+
529543
The payoff for doing this extra work, as we will see <<natural-id-cache,much later>>, is that we can take advantage of optimized natural id lookups that make use of the second-level cache.
530544

531545
Note that even when you've identified a natural key, we still recommend the use of a generated surrogate key in foreign keys, since this makes your data model _much_ easier to change.

documentation/src/main/asciidoc/introduction/Interacting.adoc

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ Modifications are automatically detected when the session is <<flush,flushed>>.
276276

277277
On the other hand, except for `getReference()`, the following operations all result in immediate access to the database:
278278

279+
[[methods-for-reading]]
279280
.Methods for reading and locking data
280281
[%breakable,cols="30,~"]
281282
|===
@@ -368,6 +369,25 @@ The following code results in a single SQL `select` statement:
368369
List<Book> books = session.findMultiple(Book.class, bookIds);
369370
----
370371

372+
[[load-by-natural-id]]
373+
As discussed <<natural-id-attributes,earlier>>, Hibernate offers the ability to map a natural id and perform load operations using that natural id.
374+
This is accomplished using the `KeyType#NATURAL` `FindOption` -
375+
376+
[source,java]
377+
----
378+
var bookKey = new BookKey(...);
379+
var book = session.find(Book.class, bookKey, NATURAL);
380+
var books = session.findMultiple(Book.class, List.of(bookKey), NATURAL);
381+
----
382+
383+
When loading by natural id, the type of value accepted depends on the type of natural id.
384+
For single-attribute natural ids, whether defined by a basic or embedded type, the attribute type should be used.
385+
For multi-attribute natural ids, Hibernate will accept a number of forms:
386+
387+
* If a link:{doc-javadoc-url}org/hibernate/annotations/NaturalIdClass.html[`@NaturalIdClass`] is defined, an instance of the natural id class may be used.
388+
* A `List` of the individual attribute values, ordered alphabetically by name, may be used.
389+
* A `Map` of the individual attribute values, keyed by the attribute name, may be used.
390+
371391
Each of the operations we've seen so far affects a single entity instance passed as an argument.
372392
But there's a way to set things up so that an operation will propagate to associated entities.
373393

@@ -595,7 +615,8 @@ Therefore, Hibernate has some APIs that streamline certain more complicated look
595615

596616
[NOTE]
597617
====
598-
Since the introduction of `FindOption` in JPA 3.2, `byId()` is now much less useful.
618+
Since the introduction of `FindOption` in JPA 3.2, `byId()` is now much less useful and deprecated.
619+
Instead, use `find()` and `findMultiple()` as discussed <<methods-for-reading,earlier>>.
599620
====
600621

601622
Batch loading is very useful when we need to retrieve multiple instances of the same entity class by id:

0 commit comments

Comments
 (0)