Issue Type: Bug Bug
Affects Versions: 4.2.0.Final, 4.0.0.Final
Assignee: Unassigned
Components: core
Created: 09/Apr/13 12:32 PM
Description:

We recently updated Hibernate from 3.x to latest 4.2.0 and started to experience problem in code deleting entities with @Version column.

Entity class (annotations for id generation are omitted):
Code:
@Entity
public class TestLock

{ @Column(name = "testLockId") @Id protected Long testLockId; @Version protected long version; }

Problematic transaction (getting EntityManager, transaction begin() and commit() are omitted):

Code:
TestLock testLock = manager.getReference(TestLock.class, testLockId);
manager.lock(testLock, LockModeType.WRITE);
manager.remove(testLock);

Stacktrace:
Code:
javax.persistence.OptimisticLockException
at org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:1413)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1329)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80)
at testlockcase.TestLockCase.main(TestLockCase.java:34)
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): testlockcase.entity.TestLock#10100
at org.hibernate.persister.entity.AbstractEntityPersister.forceVersionIncrement(AbstractEntityPersister.java:1835)
at org.hibernate.action.internal.EntityIncrementVersionProcess.doBeforeTransactionCompletion(EntityIncrementVersionProcess.java:53)
at org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:662)
at org.hibernate.engine.spi.ActionQueue.beforeTransactionCompletion(ActionQueue.java:307)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:612)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:105)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75)
... 1 more

While this example might look like a nonsense, in the real world there are things to be done between lock() and remove() and it makes sense to lock the entity.

Any ideas what might be wrong?

It looks like a bug to me, detailed logs suggest that Hibernate throws OptimisticLockException after executing query like this:

update TestLock set version=#VERSION + 1 where version=#VERSION and testLockId=#ID

which returns zero results (because the row is deleted already) - this query should not be executed after remove(), right?

Edit: This behaviour is present at least from 4.0.0.Final, as a temporary solution we are forcing PESSIMISTIC locks in our EntityManagerProxy.

Environment: >= 4.0.0 && <= 4.2.0 (did not test beta versions)
Project: Hibernate ORM
Priority: Major Major
Reporter: Martin Nedbal
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira