jakartaee / jakartaee/persistence

EntityAgent and lifecycle callbacks

Open
#1,040 1 comment 0 reactions 0 assignees View on GitHub
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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.