jakartaee / jakartaee/persistence
make Cacheable actually useful
- Dominant language
- Java
- Stars
- 268
- Forks
- 78
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 13
Description
The `@Cacheable` annotation was added in JPA 2.0 with IMO insufficient review.
Ever since then, Hibernate has been telling people not to use this annotation, and to use Hibernate's `@Cache` annotation instead.
Essentially, `@Cacheable` doesn't allow the specification of any useful entity-specific semantics.
So, consider what Hibernate has instead:
```java
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface Cache {
/**
* The appropriate {@linkplain CacheConcurrencyStrategy concurrency
* policy} for the annotated root entity or collection.
*/
CacheConcurrencyStrategy usage();
/**
* The cache region name.
*/
String region() default "";
/**
* When bytecode enhancement is used, and {@linkplain LazyGroup
* field-level lazy fetching} is enabled, specifies whether lazy
* attributes of the entity are eligible for inclusion in the
* second-level cache, in the case where they happen to be loaded.
*
* By default, a loaded lazy field will be cached when
* second-level caching is enabled. If this is not desirable—if,
* for example, the field value is extremely large and only rarely
* accessed—then setting {@code @Cache(includeLazy=false)} will
* prevent it and other lazy fields of the annotated entity from being
* cached, and the lazy fields will always be retrieved directly from
* the database.
*
* @see LazyGroup
*/
boolean includeLazy() default true;
}
```
It offers essentially three capabilities:
1. the ability to specify whether an entity is read-only, read-mostly, or highly transactional, which effects how it should be treated by the caching infrastructure,
2. the ability to specify the name of a cache "region", where different regions can have different expiry strategies, and so on, and
3. the ability to exclude `LAZY` field values from the second-level cache (this is useful for dealing with stuff like LOBs)
The first of these is by far the most important. Hibernate has four `CacheConcurrencyStrategy`s but perhaps for the purpose of the spec, we could simplify this to something like:
```java
public enum CacheConcurrency {
READ_ONLY, READ_MOSTLY, READ_WRITE
}
```
The second thing is also extremely important, but since any JPA implementation is surely going to approach it completely differently, the most I think we could do here is some sort of strongly-typed hints. Such hints could directly specify expiry timeouts and so on, or they could specify a Hibernate-style "region name". I believe we could reuse `@PersistenceProperty` for this. Yeah, yeah, I know this annotation is really intended to specify global properties/hints, but I think it's OK to reuse it here.
The third thing I'm not quite sure what to do with. One possibility would be an `@ExcludedFromCache` annotation, but it's hard to see how we could formalize the rules of such an annotation in a way which would be portable. I guess we can just leave this as something for the hints to deal with.
So, finally, we would maybe end up with something like:
```java
public enum CacheConcurrency {
READ_ONLY,
READ_MOSTLY,
READ_WRITE
}
```
```java
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface Cacheable {
/**
* (Optional) Whether or not the entity should be cached.
*/
boolean value() default true;
/**
* (Optional) Specifies whether the entity is read-only or read-mostly,
* as a hint to the persistence provider.
*/
CacheConcurrency concurrency() default CacheConcurrency.READ_WRITE;
/**
* (Optional) Additional properties for configuring the cache
* configuration. These are treated as hints by the persistence
* provider.
*/
PersistenceProperty[] properties() default {};
}
```
Thoughts?
Contributor guide
Research direction
Start by reviewing the current JPA @Cacheable annotation and the proposed CacheConcurrency and PersistenceProperty designs described in issue 977. Define the portable cache semantics and annotation changes before implementation; no files or tests are named, so the completion criteria remain unresolved in the discussion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, database
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100