jakartaee / jakartaee/persistence
access to original entity state in @PreUpdate lifecycle callback
- Dominant language
- Java
- Stars
- 268
- Forks
- 78
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 13
Description
## Problem
Currently, the @PreUpdate lifecycle callback only provides access to the
modified entity state. There is no standard way to access the original
(pre-modification) values within this callback.
## Use Cases
- Audit logging (track what changed)
- Conditional validation based on previous values
- Sending notifications only when specific fields change
- Business rules that depend on state transitions
## Current Workarounds
Developers must use vendor-specific solutions:
- Hibernate: Interceptors or Envers
- @Transient fields with @PostLoad
- Manual database queries
These approaches are:
- Non-portable across JPA implementations
- Complex and error-prone
- Performance inefficient (extra queries)
## Comparison with Other ORMs
Modern ORMs provide this feature out-of-the-box:
**Entity Framework (.NET)**
```csharp
var oldValue = entry.OriginalValues["propertyName"];
var newValue = entry.CurrentValues["propertyName"];
```
**Ruby on Rails (Active Record)**
```ruby
old_value = name_was
new_value = name
```
**Sequelize (Node.js)**
```javascript
oldValue = instance._previousDataValues.name;
newValue = instance.dataValues.name;
```
## Proposed Solution
### Option A: Additional callback parameter
```java
@PreUpdate
public void beforeUpdate(EntityChangeSet changeSet) {
for (String property : changeSet.getModifiedProperties()) {
Object oldValue = changeSet.getOriginalValue(property);
Object newValue = changeSet.getCurrentValue(property);
// audit logic
}
}
```
### Option B: New annotation
```java
@PreUpdate
public void beforeUpdate() {
// current behavior
}
@PreUpdateWithChanges
public void beforeUpdateWithChanges(EntityChangeSet changeSet) {
// access to original values
}
```
### Option C: EntityManager API enhancement
```java
@PreUpdate
public void beforeUpdate() {
EntityChangeSet changes = entityManager.getChangeSet(this);
Object oldValue = changes.getOriginalValue("propertyName");
}
```
## Benefits
- Portable across all JPA implementations
- Simpler, cleaner code
- Better performance (no extra queries)
- Consistency with other modern ORM frameworks
- Backward compatible (doesn't break existing code)
## Questions
- Would this be feasible for Jakarta Persistence 4.0?
- Are there technical limitations I'm not considering?
- Which API approach would be preferred by the spec team?
```
Contributor guide
Research direction
The issue names no repository files, tests, or entry points. Start by reviewing the existing @PreUpdate lifecycle-callback contract and comparing proposed options A–C for feasibility and portability. Done means the spec team has selected an API direction and recorded concrete scope and compatibility requirements.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design, databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100