简体   繁体   中英

Create and find a jpa entity in the same transaction?

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:

1. Create entityA
2. Persist entityA
3. entityB = find entityA
4. lock(entityB, PESSIMISTIC_WRITE)

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:

1. Create entityA
2. Persist entityA
3. lock(entityA, PESSIMISTIC_WRITE)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM