I have a Grails app where people login through Spring Security. Their user domain is then loaded onto the session for the duration of being logged in.
I get a StaleObjectStateException when another user preforms an action that updates a counter on a user object in the database user.save(flush:true)
that's currently on another session of a logged in user
E.g. I have "User A" object on the session for logged in User A. Then when a User B is logged in, and preforms an action to update the User A object but the version is out of sync.
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.example.User#2]
at $Proxy12.merge(Unknown Source)
I've tried merging but no luck.
I'm thinking of completely taking out the "version" property as there are so many updates on the user domain as hundreds of users would be logged in. But I don't know what affect this would have on the consistency of the data over time.
Would swapping user.save(flush:true)
to User.executeUpdate(Update viewCount where ...)
sol开发者_运维百科ve the problem and bring more caching issues?
Or can I select specific properties that can ignore "version" when updating them. I don't really understand whats going on though with this example. http://grails.1312388.n4.nabble.com/GORM-setting-access-field-td1592837.html
So how can I solve this?
Solved: Basically don't have the user domain on the session. Just the users Id. So you can load the domain when you need to use it.
The solution is not to use a domain object inside the session. Use the id instead, and then load the object for each request that needs the user data. It's differences introduced in spring security plugin for grails. For more info have a look here (official docs):
http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/guide/2%20Differences%20Between%20the%20Spring%20Security%20and%20Acegi%20Plugins.html
精彩评论