HHH-11142 - Document supported use/implications of @Cache / @Cacheable
(cherry picked from commit 88bc2db28a
)
This commit is contained in:
parent
305e738478
commit
74a9acc616
|
@ -118,6 +118,53 @@ include::
|
|||
The default value is `all` so lazy properties are cacheable.
|
||||
The other possible value is `non-lazy` so lazy properties are not cacheable.
|
||||
|
||||
[[caching-mappings-inheritance]]
|
||||
=== Entity inheritance and second-level cache mapping
|
||||
|
||||
When using inheritance, the JPA `@Cacheable` and the Hibernate-specific `@Cache` annotations should be declared at the root-entity level only.
|
||||
That being said, it is not possible to customize the base class `@Cacheable` or `@Cache` definition in subclasses.
|
||||
|
||||
Although the JPA 2.1 specification says that the `@Cacheable` annotation could be overwritten by a subclass:
|
||||
|
||||
[quote, Section 11.1.7 of the JPA 2.1 Specification]
|
||||
____
|
||||
The value of the `Cacheable` annotation is inherited by subclasses; it can be
|
||||
overridden by specifying `Cacheable` on a subclass.
|
||||
____
|
||||
|
||||
Hibernate requires that a given entity hierarchy share the same caching semantics.
|
||||
|
||||
The reasons why Hibernate requires that all entities belonging to an inheritance tree share the same caching definition can be summed as follows:
|
||||
|
||||
- from a performance perspective, adding an additional check on a per entity type level would slow the bootstrap process.
|
||||
- providing different caching semantics for subclasses would violate the https://en.wikipedia.org/wiki/Liskov_substitution_principle[Liskov substitution principle].
|
||||
+
|
||||
Assuming we have a base class, `Payment` and a subclass `CreditCardPayment`.
|
||||
If the `Payment` is not cacheable and the `CreditCardPayment` is cached, what should happen when executing the following code snippet:
|
||||
+
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
Payment payment = entityManager.find(Payment.class, creditCardPaymentId);
|
||||
CreditCardPayment creditCardPayment = (CreditCardPayment) CreditCardPayment;
|
||||
----
|
||||
+
|
||||
In this particular case, the second level cache key is formed of the entity class name and the identifier:
|
||||
+
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
keyToLoad = {org.hibernate.engine.spi.EntityKey@4712}
|
||||
identifier = {java.lang.Long@4716} "2"
|
||||
persister = {org.hibernate.persister.entity.SingleTableEntityPersister@4629}
|
||||
"SingleTableEntityPersister(org.hibernate.userguide.model.Payment)"
|
||||
----
|
||||
+
|
||||
Should Hibernate load the `CreditCardPayment` from the cache as indicated by the actual entity type, or it should not use the cache since the `Payment` is not supposed to be cached?
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Because of all these intricacies, Hibernate only considers the base class `@Cacheable` and `@Cache` definition.
|
||||
====
|
||||
|
||||
[[caching-query]]
|
||||
=== Entity cache
|
||||
|
||||
|
|
Loading…
Reference in New Issue