jamesfredley commented on issue #14935:
URL: https://github.com/apache/grails-core/issues/14935#issuecomment-3936181360
After investigating this, this appears to be expected JPA/Hibernate behavior
rather than a GORM bug.
When you call `merge()` on a detached entity, Hibernate performs a version
check as part of its optimistic locking strategy. If the entity was detached
while at version N, and another transaction has since updated it to version
N+1, the `merge()` will throw an `OptimisticLockingException`. This is by
design - it prevents the "last write wins" problem by ensuring you don't
silently overwrite changes made by another transaction.
The typical patterns for handling this are:
1. **Re-read before merge**: Fetch a fresh copy from the database, apply
your changes to it, then save:
```groovy
def fresh = MyDomain.get(detachedInstance.id)
fresh.someProperty = detachedInstance.someProperty
fresh.save()
```
2. **Catch and retry**: Wrap the merge in a try/catch for
`OptimisticLockingException` and retry with a fresh read.
3. **Use `discard()` + `refresh()`**: If you want to abandon local changes
and reload from the database.
The Hibernate documentation covers this in detail under [Optimistic
Locking](https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#locking-optimistic).
--
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]