2013-05-31 22 views
5

我正在使用JPA EntityManager來執行一些操作,並且其中一項操作是將實體替換爲具有相同@Id的另一個實體。因此,給定oldObjectnewObject,刪除oldObject並將其替換爲newObject的最佳方法是什麼?使用EntityManager替換實體的最佳方法

下面是一些代碼不工作:

try 
{ 
    entityManager.getTransaction().begin(); 
    entityManager.remove(oldObject); 
    entityManager.persist(newObject); 
    entityManager.getTransaction().commit(); 
} 
catch (PersistenceException persistExc) 
{ 
    entityManager.getTransaction().rollback(); 
    // do some stuff 
} 

這段代碼獲得以下異常:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.depressio.SomeObject 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1154) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:678) 

現在,當然它的工作原理確定的,如果不是刪除實體,我只是更新其已更改的字段。然而,我只是被賦予了新的對象(UI通過REST向我拋棄),所以我實在沒有任何線索已經改變的線索,所以我必須每字段更新。如果有很多的領域,這並不理想。

我覺得我對於如何正確地進行刪除有點困惑。我認爲EntityManager.remove是正確的方式,但我想不是。

在此先感謝!

編輯1:我覺得我應該注意oldObject.id == newObject.id。 id通過@SequenceGenerator生成。如果標識符已用生成器註釋,我是否允許使用標識符持久化對象?

編輯2:根據最高回覆的答案here,因爲@Id已經定義,並且它是一個自動生成的字段,所以Hibernate認爲它已被分離。現在我知道爲什麼我得到的例外,但解決方案仍不清楚。

回答

4

這就是EntityManager.merge()所做的。將它傳遞給新的分離的實體,並將它的狀態合併到舊的附屬實體。分離的實體將保持分離,並且舊分離的實體將保持連接,但將其狀態替換爲新分離的實體的狀態。

+0

哦,上帝,這很尷尬。出於某種原因,我認爲「合併」只與附屬實體一起工作,而不是分離的實體。我猜它可以爲兩者工作,是吧?無論如何,這解決了這個問題......我太傻了。謝謝! – Depressio

+0

合併附加實體不會執行任何操作,除了將級聯合並註釋爲級聯MERGE或ALL註釋的關聯外。 –

+0

如果我修改附屬實體會怎麼樣?自從附加後,我甚至必須合併嗎?我得到的印象是,不,我沒有。 – Depressio