We have an application in production using Spring 2.0 and Hibernate 3.24 and Oracle 10g. We are attempting to upgrade to Spring 2.5.6. When testing the upgrade, we are consistently encountering StaleObjectStateException when updating a Hibernate-persisted Order object with a many-to-one association with a Subscription object (mapping excerpts and exception stack trace below). The Java code and Hibernate mappings have not been touched for quite some time. It is clear that an UPDATE subscription SET .. WHERE subscription_id = ? and updated_date = ? statement is being executed as a result of a session.update(order) since cascade is set to “save-update”. It is also clear that that statement is modifying zero rows (according to Oracle) resulting in the StaleObjectStateException. What I don't know is: Why? I can reproduce this behavior locally with no possibility of a concurrent modification. Even more puzzling, why is this happening as the result of a Spring upgrade? I've spent all week on this problem. Any insight is most welcome.
Code:
<hibernate-mapping>
<class name="Subscription" table="SUBSCRIPTION">
...
<timestamp name="updatedDate" column="UPDATED_DATE"/>
...
</class>
</hibernate-mapping>
Code:
<hibernate-mapping default-cascade="none" auto-import="false">
<class name="Order" table="ORDER">
...
<many-to-one name="subscription" cascade="save-update"
class="Subscription" column="SUBSCRIPTION_ID" outer-join="false"
not-null="false"/>
...
</class>
</hibernate-mapping>
Code:
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [dumas.app.subscription.Subscription#2971056]
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1714)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2357)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2257)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2557)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)