2010-06-04 28 views
3

我有部分,而params之間的一個一對多的關係(「部分」有很多個「PARAMS)副本孩子收集到另一個對象

我試圖做一些幼稚這樣的:。

Part sourcePart = em.find(Part.class, partIdSource); 
Part destPart = em.find(Part.class, partIdDest); 

Collection<Param> paramListSource = sourcePart.getParamList(); 

destPart.setParamList(paramListSource); 

基本上我想複製所有參數從sourcePart到destPart。希望持久性提供者將自動在參數表/實體設置正確的外鍵。

上面的代碼將顯然是不行的。

有沒有簡單的方法來做到這一點,或者我必須做一個新的集合,然後添加每個參數(創建新的參數,設置屬性等)?

編輯

我第一次嘗試脫離實體就像有人在另一個線程建議,但我得到一個異常(org.hibernate.PersistentObjectException:通過堅持脫離實體:shared.entity.Param)。

Part sourcePart = em.find(Part.class, partIdSource); 
// force eager loading... 
((List)sourcePart.getParamList()).get(0); 

Part destPart = em.find(Part.class, partIdDest); 

// detach entity 
org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession(); 
session.evict(sourcePart); 

//causes exception "detached entity passed to persist" 
destPart.setParamList(sourcePart.getParamList()); 
+0

目前還不清楚,你是否希望在參數中更改FK,以便它們指向destPart,是否要創建除FK外相同的新參數,還是希望參數能夠共享由兩部分? – Affe 2010-06-04 06:25:41

+0

我想要新的相同的參數,除了FK。對不起,因爲它不清楚:) – Bogdan 2010-06-04 06:36:04

回答

2

基本上我想複製所有參數從sourcePart到destPart。希望持久性提供者會自動在Param表/實體中設置正確的外鍵。

如果你想要去的「逐出方式」,使您的實體獨立不夠的,你需要「抵消」的Id屬性,以便您的實體成爲再次(堅持他們必須導致SQL INSERT)。在僞代碼:

MyObject ob = session.get(idOfExisting); 
hibernate.evict(ob); 
ob.setId(null); 
hibernate.save(ob); 

但我覺得這很髒。我將迭代列表中的項目並使用複製構造函數(而不復制Id屬性)來創建新列表,然後在目標對象上設置副本(這將與提供程序無關)。

+0

我最終使用了複製構造函數。儘管看起來我需要在Param中設置目標零件實例,否則它將不知道要設置的外鍵。我認爲這將自動完成... 謝謝你的建議! – Bogdan 2010-06-06 13:02:07

1

也許你可以在Param中實現clone()方法。那麼你可以做paramListSource.clone()

+0

克隆類型的糟糕,因爲它返回對象。改爲使用克隆構造函數: Param(Param toClone) 另外,我沒有看到如何保證Collection的特定實現具有clone(),因此它可以進行深層複製。 – 2010-06-04 07:11:33

+0

嗨,Daniel,尼克。我最終會實現這樣的事情。但我希望所有這些持久層都更強大一些,並且可以在這些情況下提供幫助。 – Bogdan 2010-06-04 07:13:29

+0

它不需要返回Object,即使它繼承自Object實際上可以執行'public MyClass clone()',它就會工作,編譯器會意識到你覆蓋了Object.clone()方法。另外不要忘記調用'(MyClass)super.clone()'來確保你得到的對象實際上是你調用它的類的一個實例(如果你擴展了MyClass並從那裏調用它)。並記住super.clone()返回一個淺拷貝,所以你需要做所有使它們獨立的工作。 – 2010-06-04 07:30:49

1

我很確定你得到的不是實際的Param實例,而是實現Param接口的代理對象,所以你可能需要創建新的Param對象並複製屬性。此外,不要將它們從會話中分離出來,因爲如果它們是代理,它們將無法在Id之外獲取其他屬性,這是唯一最初填充的內容(延遲獲取)。

+0

這是有效的,即使我不喜歡sourcePart.getParamList())。get(0)? 不應該這個強制提取嗎? – Bogdan 2010-06-04 10:46:09

+0

我很確定,如果你想創建一個新的對象,你需要創建一個新的對象,這是實際的類,而不是代理,並沒有任何額外的東西像id(這應該得到自動填充)或其他任何填充屬性,然後再嘗試保留它。 – 2010-06-04 14:46:55

相關問題