在同一个交易中创建并找到一个jpa实体?

时间:2012-07-24 11:04:19

标签: java hibernate jpa jboss7.x

我正在使用JBoss 7.1.1和它附带的Hibernate的默认实现(4.0.1)。 我有一个消息驱动的bean,它在同一个事务中创建一个实体并使用实体管理器持久化它。之后(仍然是相同的事务)我找到新创建的实体并尝试使用实体管理器用PESSIMISTIC_WRITE锁定它,但我得到一个OptimisticLockException。其根源如下:

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

为什么我无法查找新创建的实体?另外,如何在创建后立即将其用于搜索?使用EM的合并方法似乎没有帮助...

1 个答案:

答案 0 :(得分:2)

我对您的问题的理解是,在您的消息驱动Bean的事务中,您正在执行以下操作:

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

和第4步抛出异常。

我认为Hibernate可能没有刷新2到3之间的持久性,所以此时A(和B)有版本0.然后Hibernate在lock()开始时刷新A的持久性,这意味着B现在有一个陈旧的版本。

你可以尝试在find之前刷新persist(所以在2之后是entityManager.flush())。

或者您应该能够跳过查找,因为entityManager.persist(entityA)使entityA成为托管对象,因此以下序列可能有效:

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