3
我有一種方法接收JPA Entity
及其相關的EntityManager
作爲參數。 Entity
實例不是在類內部創建的,它很可能被其他類共享(如GUI等)。JPA:回滾後刷新分離的實體並重新附加它
該方法啓動一個事務,對實體進行一些更改,並最終提交事務。
如果提交失敗,則調用EntityTransaction.rollback()
:根據JPA規範,實體將從管理器中分離。
在故障情況下的應用需要放棄掛起的更改,恢復實體e
內的原始值,並將其重新連接到EntityManager
,這樣對e
對象的各個分散的引用將繼續有效。這個問題引起了這裏:我的理解是,這是不使用EntityManager
的API來簡單的操作:由於e
被分離
- 調用
EntityManager.refresh(e)
是不可能的。 - 做
e = EntityManager.merge(e)
會爲e
創建一個新實例:運行時程序中對原始e
的所有其他引用都不會更新爲新實例。這是主要問題。此外(實際上對此不太確定),EntityManager.merge(e)
將用當前由e
保持的值(即,可能導致提交失敗的值)來更新新的託管實例的值。相反,我需要的是重置它們。
示例代碼:
public void method(EntityManager em, Entity e) {
EntityTransaction et = em.getTransaction();
et.begin();
...
// apply some modifications to the entity's fields
...
try {
et.commit();
} catch (Exception e) {
et.rollback();
// now that 'e' is detached from the EntityManager, how can I:
// - refresh 'e', discarding all pending changes
// - without instantiating a copy (i.e. without using merge())
// - reattach it
}
}
什麼是在這種情況下,最好的辦法?
是否給定的實體'e'有任何變化,這是不將提交給數據庫了嗎? – Uooo
該實體需要進行哪些其他操作,以便您需要遵循對其的引用?解決這種情況的一個基本方法是創建一個幹運行以確保不會發生回滾。另一個基本的方法是創建一個子交易,基本上克隆實體網絡以作爲預期回滾的承諾。 –
@Uooo:不,該方法假定'e'的狀態在作爲參數傳遞時與數據庫行同步。 @BobDalgleish:'e'對象本身可能被其他(未知)類引用,它們可以在不同的事務中分別修改它的其他字段(儘管不是併發)。我希望存在一些非複雜的重置和重新連接策略。你的方法也很有用。 –