jakartaee / jakartaee/persistence
EntityAgent and lifecycle callbacks
- Dominant language
- Java
- Stars
- 267
- Forks
- 78
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 13
Description
The spec says:
> In general, the lifecycle method of a portable application should not invoke `EntityManager` or query operations, access other entity instances, or modify relationships within the same persistence context.
[I'm not entirely sure what "in general" means here. Does it mean "usually" or does it mean ∀?]
Anyway, that doesn't say anything about `EntityAgent`.
In principle, an `EntityAgent` doesn't need to hold any of the sort of volatile state that would be messed up by reentrant calls, so it would be plausible to explicitly relax this restriction in the case of an `EntityAgent`. (The implementation of `EntityAgent` in Hibernate is *not* currently completely safe for reentrant calls, but we could fix that quite easily.)
So that's the first question: what to say here about `EntityAgent`.
But I'm also thinking we should consider making it even easier for a callback listener to get hold of an `EntityAgent`, even when the surrounding work is being done in an `EntityManager`. When using an entity listener class In a CDI environment, there's now a good a way to do that, just use `@PersistenceAgent EntityAgent agent`.
```java
@Dependent
@EntityListener
class AuditListener {
@PersistenceAgent EntityAgent agent;
@PostInsert
void writeAuditLog(Object entity) {
agent.insert(AuditRecord.forCreation(entity));
}
@PostUpdate
void writeAuditLog(Object entity) {
agent.insert(AuditRecord.forModification(entity));
}
}
```
But that doesn't help when:
- CDI is not available, nor
- when the callback is defined directly on the entity class.
Now, use of an `EntityAgent` directly from an entity class is in my view a debatable practice in a conventional JPA architecture, but with stuff like Panache (i.e Active Record) it's legit. And of course CDI is not available everywhere.
So I wonder if we could say that callback listeners are allowed to declare a parameter accepting `EntityAgent`?
```java
@EntityListener
class AuditListener {
@PostInsert
void writeAuditLog(Object entity, EntityAgent agent) {
agent.insert(AuditRecord.forCreation(entity));
}
@PostUpdate
void writeAuditLog(Object entity, EntityAgent agent) {
agent.insert(AuditRecord.forModification(entity));
}
}
```
WDYT?
Contributor guide
Research direction
No files or tests are named. Start by reading the quoted lifecycle-callback restriction and the existing EntityAgent, CDI injection, and entity-listener examples in the issue. Done means reaching a decided specification for EntityAgent reentrancy and whether callback methods may accept an EntityAgent parameter.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100