jakartaee / jakartaee/persistence

make Cacheable actually useful

Open
#977 0 comments 0 reactions 0 assignees View on GitHub
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.

Image

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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.