jamesfredley commented on issue #14935:
URL: https://github.com/apache/grails-core/issues/14935#issuecomment-3930840467
scenario (from `exampleAppSimple2` / `exampleAppGrails700M5`):
1. Create + update entity - DB version=1
2. Load `ds1` (v=1) and `ds2` (v=1) in separate sessions
3. Update via `ds1` - DB version=2
4. Try update via `ds2` - correctly gets `OptimisticLockingFailureException`
(v=1 vs DB v=2)
5. Call `ds2.merge()` expecting an attached copy with DB's version=2 and
their `name` change applied
6. Gets `ds2Copy.version == 1` (detached version) - eventual
`OptimisticLockingException` at flush
## Why This Is Expected
GORM's `performMerge()` is a straight pass-through to Hibernate's
`session.merge()` with no custom version handling:
```groovy
// AbstractHibernateGormInstanceApi.groovy
protected D performMerge(final D target, final boolean flush) {
hibernateTemplate.execute { Session session ->
Object merged = session.merge(target)
session.lock(merged, LockMode.NONE)
if (flush) { flushSession(session) }
return (D) merged
}
}
```
Hibernate 5.6's `DefaultMergeEventListener.entityIsDetached()` does exactly
this:
```java
// 1. Load entity from DB
final Object result = source.get(entityName, clonedIdentifier); // version=2
// 2. Check version mismatch
else if (isVersionChanged(entity, source, persister, target)) {
throw new StaleObjectStateException(entityName, id); // Fires here
}
// 3. Only if versions match: copy state
copyValues(persister, entity, target, source, copyCache);
```
`merge()`
- Copies **ALL state** from detached to managed (including version)
- Uses the version specifically for **conflict detection**
- Throws immediately if versions don't match
The correct pattern for "load fresh + apply my changes" is:
```groovy
Example.withNewTransaction {
Example fresh = Example.get(ds2.id) // version=2 from DB
fresh.name = ds2.name // apply only desired changes
fresh.save() // succeeds
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]