2012-07-24 53 views
3

我正在使用JBoss 7.1.1和它自帶的Hibernate的默認實現(4.0.1)。 我有一個消息驅動的bean,在同一個事務中創建一個實體並使用實體管理器持久化它。之後(仍然是同一個事務),我找到新創建的實體並嘗試使用實體管理器用PESSIMISTIC_WRITE鎖定它,但是我得到了一個OptimisticLockException。它的根源如下:在同一個事務中創建並找到一個jpa實體?

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的合併方法似乎並沒有幫助...

回答

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現在有一個陳舊的版本。

你可以嘗試在查找之前刷新持久化(在2)之後的entityManager.flush()。

或者你應該能夠跳過發現,自從entityManager.persist(entityA)使entityA託管對象,所以下面的順序可以工作:

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

感謝,沖洗並獲得成功:) – 2012-07-24 12:20:23

+0

大:-)你應該嘗試避免刷新與創建/ persist /鎖定 - 如果這樣做會更有效率...... – MattR 2012-07-24 12:27:38

+0

不幸的是,應用程序邏輯將不會允許這 - 我將不得不重構噸的代碼在沒有這樣的問題的情況下寫入了ejb 2.1。沖洗中間交易不好? – 2012-07-25 11:53:05

相關問題