I’m using JBoss 7.1.1 and the default implementation of Hibernate that comes with it (4.0.1).
I have a message driven bean, that in the same transaction creates an entity and persists it using the entity manager. After that (still the same transaction) I find the newly created entity and try to use the entity manager to lock it with PESSIMISTIC_WRITE, but I get an OptimisticLockException. Its root is as follows:
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [some.package.name.EntityName#aaa1a1a0-d568-11e1-9f99-d5a00a0a12b6]
at org.hibernate.dialect.lock.PessimisticWriteSelectLockingStrategy.lock(PessimisticWriteSelectLockingStrategy.java:95)
at org.hibernate.persister.entity.AbstractEntityPersister.lock(AbstractEntityPersister.java:1785)
at org.hibernate.event.internal.AbstractLockUpgradeEventListener.upgradeLock(AbstractLockUpgradeEventListener.java:99)
at org.hibernate.event.internal.DefaultLockEventListener.onLock(DefaultLockEventListener.java:85)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:693)
at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:686)
at org.hibernate.internal.SessionImpl.access$1100(SessionImpl.java:160)
at org.hibernate.internal.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2164)
at org.hibernate.ejb.AbstractEntityManagerImpl.lock(AbstractEntityManagerImpl.java:1093)
... 202 more
Any ideas why I can’t look up the newly created entity? Also, how can I make it available for searching right after it is created? Using the merge method of the EM doesn’t seem to help …
My understanding of your question is that within your message driven bean’s transaction you’re doing the following:
and step 4 is throwing an exception.
I think Hibernate may not have flushed the persist between 2 and 3 so at that point A (and B) have version 0. Hibernate is then flushing the persist of A at the start of the lock(), which means B now has a stale version.
You could try flushing the persist before the find (so entityManager.flush() after 2).
Or you should be able to skip the find, since entityManager.persist(entityA) makes entityA a managed object, so the following sequence may work: