How to fix StaleObjectStateException using JPA and Hibernate

Controller Logic:

def updateObject() { Object o = Object.get(params.id as Long) o.otherObjects.clear() objectDataService.saveObject(o.id) OtherObject newObject = new OtherObject; o.addToOtherObjects(newObject) objectDataService.saveObject(o.id) } 

Servicelogic

 def saveObject(long profileId) { o.save(flush:true) } 

what's happening

in 90% of cases this will work.

Problems

 ERROR errors.GrailsExceptionResolver - StaleObjectStateException occurred when processing request: [GET] /controller/updateObject - parameters: stuff[]: data Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.path.Object#1]. Stacktrace follows: Message: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.path.Object#1] 

I read related questions and found the merge call you see above. he allowed about 50% of cases, but not all.

+7
hibernate grails gorm
source share
3 answers

For us, several different approaches finally resolved the StaleObjectException exception:

 object = object.refresh() 

Updating objects after restoring them has allowed most of our StaleObjectExceptions. Especially in cases where it was possible that someone would work on the same object from another place and change some of its members (most problems were received with members of the collection).

Overall project stability:

 wrongly linked resources 

we had 404 in a specific resource file that we actually did not need, and therefore he ignored it for a while. it turns out that the missing file will cause the session to remain open - thus creating StaleObjects left and right.

Therefore, as a hint for anyone who encounters more than usual (some StaleObjects can always occur - see answers above) StaleObjectExceptions: make sure that all resources are connected correctly and your developer tools (Chrome F12) do not report any missing files.

+2
source share

StaleObjectStateException:

As already mentioned about this exception. When an invalid domain domain with a version is in a session during a flash (explicit or implicit), the version number is dialed, but it is not stored in the database. Then, when it becomes valid again and is saved and discarded, hibernate considers it obsolete because the version number does not match the version in the database and it throws a StaleObjectStateException.

It can be decided how.

  • you need to know the value of the version before performing the update, if it is 1, then you need to update using the program. with a specific update operation.
  • Using the @version annotation.

About @version:

The version number mechanism for optimistic locking is provided through the @Version annotation. Example: @Version annotation

 @Entity public class Flight implements Serializable { ... @Version @Column(name="OPTLOCK") public Integer getVersion() { ... } } 

Here, the version property is mapped to the OPTLOCK column, and the entity manager uses it to detect conflicting updates and prevents the loss of updates that will be overwritten by the strategy of the latest @version battles

For more information about Grails, see the link below containing the Git code of the hub.
test for GRAILS-8937: HibernateOptimisticLockingFailureException

+5
source share

StaleObjectStateException can occur naturally in any other project. Each time when two parallel transactions load the same version of an entity, and each of them changes this object, you end the failure of the last executable thread, due to an unstable collision failure.

In your case, there is an additional call outside the JPA that can alleviate this problem:

 Object o = PObject.lock(profileId) 

Each transaction is tied to a thread and executed inside the session, so two competing threads keep two object references for the same object identifier. The optimistic locking target works effectively without any other explicit locking mechanism.

If you send a link to a modified entity to the saveObject version, and you still get this exception, it means that you have a high probability that two competing threads will modify the same objects.

In this scenario, a pessimistic castle will give better results because it includes anticipation rather than an optimistic fail-safe approach .

+4
source share

All Articles