Search code examples
springhibernategrailsgrails-ormgrails-2.0

StaleObjectStateException: Row was updated or deleted by another transaction?


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:

  1. here that you can use discard()
  2. here that you can use merge()

Which one should I use?


Solution

  • 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)