I do the following:
def currentUser = springSecurityService.currentUser
currentUser.name = "test"
currentUser.save(flush: true)
// some other code
currentUser.gender = "male"
currentUser.save(flush: true) // Exception occurs
This is the exception I get:
ERROR events.PatchedDefaultFlushEventListener - Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
How can I prevent this error? What is the best solution for that?
I found different approaches:
Which one should I use?
You should use merge - it will update the object to match the current state in the database. If you use discard it will reset the object back to what the database has, discarding any changes. Everything else in the hibernate session you need to manage yourself.
More importantly code should be written in a service so that there is a database transaction, and you should use
save(flush:true)
once only at the end.
def currentUser = springSecurityService.currentUser
currentUser.name = "test"
// currentUser.save(flush: true) // removing this line because if a rollback occurs, then changes before this would be persisted.
// some other code
currentUser.gender = "male"
currentUser.merge() // This will merge persistent object with current state
currentUser.save(flush: true)