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/introduction/Advanced.adoc
+78-1Lines changed: 78 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -584,4 +584,81 @@ There are a number of annotations which are useful to express this sort of compl
584
584
| `@JoinColumn` | Specifies the foreign key column
585
585
|===
586
586
587
-
Of course, `@Any` mappings are disfavored, except in extremely special cases, since it's much more difficult to enforce referential integrity at the database level.
587
+
Of course, `@Any` mappings are disfavored, except in extremely special cases, since it's much more difficult to enforce referential integrity at the database level.
588
+
589
+
[[bytecode-enhancer]]
590
+
=== Using the bytecode enhancer
591
+
592
+
:enhancer: {userGuideBase}#BytecodeEnhancement
593
+
594
+
Hibernate's {enhancer}[bytecode enhancer] enables the following features:
595
+
596
+
- _attribute-level lazy fetching_ for basic attributes annotated `@Basic(fetch=LAZY)` and for lazy non-polymorphic associations,
597
+
- _interception-based_—instead of the usual _snapshot-based_—detection of modifications.
598
+
599
+
To use the bytecode enhancer, we must add the Hibernate plugin to our gradle build:
600
+
601
+
[source,groovy]
602
+
----
603
+
plugins {
604
+
id "org.hibernate.orm" version "6.2.2.Final"
605
+
}
606
+
607
+
hibernate { enhancement }
608
+
----
609
+
610
+
// [discrete]
611
+
// ==== Attribute-level lazy fetching
612
+
613
+
Consider this field:
614
+
615
+
[source,java]
616
+
----
617
+
@Entity
618
+
class Book {
619
+
...
620
+
621
+
@Basic(optional = false, fetch = LAZY)
622
+
@Column(length = LONG32)
623
+
String fullText;
624
+
625
+
...
626
+
}
627
+
----
628
+
629
+
The `fullText` field maps to a `clob` or `text` column, depending on the SQL dialect.
630
+
Since it's expensive to retrieve the full book-length text, we've mapped the field `fetch=LAZY`, telling Hibernate not to read the field until it's actually used.
631
+
632
+
- _Without_ the bytecode enhancer, this instruction is ignored, and the field is always fetched immediately, as part of the initial `select` that retrieves the `Book` entity.
633
+
- _With_ bytecode enhancement, Hibernate is able to detect access to the field, and lazy fetching is possible.
634
+
635
+
[TIP]
636
+
====
637
+
By default, Hibernate fetches all lazy fields of a given entity at once, in a single `select`, when any one of them is accessed.
638
+
Using the `@LazyGroup` annotation, it's possible to assign fields to distinct "fetch groups", so that different lazy fields may be fetched independently.
639
+
====
640
+
641
+
Similarly, interception lets us implement lazy fetching for non-polymorphic associations without the need for a separate proxy object.
642
+
However, if an association is polymorphic, that is, if the target entity type has subclasses, then a proxy is still required.
643
+
644
+
// [discrete]
645
+
// ==== Interception-based change detection
646
+
647
+
Interception-based change detection is a nice performance optimization with a slight cost in terms of correctness.
648
+
649
+
- _Without_ the bytecode enhancer, Hibernate keeps a snapshot of the state of each entity after reading from or writing to the database.
650
+
When the session flushes, the snapshot state is compared to the current state of the entity to determine if the entity has been modified.
651
+
Maintaining these snapshots does have an impact on performance.
652
+
- _With_ bytecode enhancement, we may avoid this cost by intercepting writes to the field and recording these modifications as they happen.
653
+
654
+
[CAUTION]
655
+
====
656
+
Interception-based change detection is less accurate than snapshot-based dirty checking.
657
+
For example, consider this attribute:
658
+
659
+
[source,java]
660
+
byte[] image;
661
+
662
+
Interception is able to detect writes to the `image` field, that is, replacement of the whole array.
663
+
It's not able to detect modifications made directly to the _elements_ of the array, and so such modifications may be lost.
0 commit comments