0

I am developing a desktop application (swing, input form) with a save button to merge back changes. The idea is that (complicated) validation and update logic may fail and the user should change some data in this form or another (opened in parallel). Then, ideally, the save button should work. In any case, hitting save twice should result in the same outcome.

However, I have learned

Entity state and entity id value in JPA/Hibernate after rollback

and here

http://www.theserverside.com/news/thread.tss?thread_id=45173

that entities might not be reused after a rollback.

For both transaction-scoped and extended persistence contexts, transaction rollback causes all pre-exist-ing managed instances and removed instances[31] to become detached. The instances’ state will be the state of the instances at the point at which the transaction was rolled back. Transaction rollback typically causes the persistence context to be in an inconsistent state at the point of rollback. In particular, the state of version attributes and generated state (e.g., generated primary keys) may be inconsistent. Instances that were formerly managed by the persistence context (including new instances that were made persistent in that transaction) may therefore not be reusable in the same manner as other detached objects—for example, they may fail when passed to the merge operation.[32]

Various workarounds are thinkable here (throwing away the changes and refreshing the entity,...).

However, the thread is from 2007 and a colleague pointed out the information might not be up to date.

The exceptions are

javax.persistence.OptimisticLockException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [de.dundm.av.shared.model.entities.Position#3288110]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:1785) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1705) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1206) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
at sun.reflect.GeneratedMethodAccessor1993.invoke(Unknown Source)
...
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [de.dundm.av.shared.model.entities.Position#3288110]
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:338) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:186) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:886) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:868) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:277) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:474) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:343) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:186) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
... 66 common frames omitted

What is essentially happening is that the rolled back (versioned) entity is merged again and this fails the second time around.

Community
  • 1
  • 1
Markus Barthlen
  • 389
  • 4
  • 15
  • try to join all actions in same transaction.. this help me in the past. – ZaoTaoBao Feb 24 '16 at 13:53
  • That is an optimistic locking exception. Either one of two things has happened. First, some transaction which modified the specified Position entity has been committed prior to the point you loaded your current Position instance into memory from the database (traditional optimistic locking, someone modified it since you loaded it) or the post you referred to is correct and the Version attributes are in an inconsistent state. – Pace Feb 24 '16 at 14:50
  • THat should be "after the point" not "prior to the point" – Pace Feb 24 '16 at 15:12
  • The database showed no changes. I therefore assume it is the way the version is tracked internally in Hibernate which is causing problems. Thank you for your answer by the way. – Markus Barthlen Feb 24 '16 at 15:17
  • There are two transactions, the first one which rolls back and the second one (on hitting the save button a second time, possibly after doing changes) with the above exception. – Markus Barthlen Feb 24 '16 at 15:19

0 Answers0