2013-05-18 129 views
0
Session session = HibernateUtil.getSessionFactory().openSession(); 
Transaction tx = session.beginTransaction(); 
Course c1 = (Course) session.get(Course.class, 1); 
tx.commit(); 
session.close(); 
c1.setCategory("science"); 
c1.setFee("3000"); 

//C1 became detached instance here 

session = HibernateUtil.getSessionFactory().openSession(); 
tx = session.beginTransaction(); 
Course c2 = (Course) session.get(Course.class, 1); 
c2.setCategory("social"); 
c2.setRecommendedBook("Modern History"); 
session.merge(c1); 
tx.commit(); 
session.close(); 

比方說我的初始數據庫表中的數據是
類別合併detatched實例數據=數學
費= 1000
recommendedBook =數學魔術

我以爲上面的代碼複製少見領域從C1到C2,並用C1覆蓋C2的公共字段。因此,預期的結果將是
類別=科學
費= 3000
recommendedBook =近代史

但它簡單地複製整個C1數據轉化爲C2和更新的數據庫與C1,和我所有的C2數據lost.Actual結果
類別=科學
費= 3000
recommendedBook =數學魔術
因此,它不逸岸合併,而是完全覆蓋。如何獲得我的預期結果?休眠:到持久化實例

回答

3

您看到的行爲是預期的。 Hibernate如何知道某些字段必須合併,而其他字段則不能? null是所有字段的有效值,並通過合併將字段設置爲null是完全有效的操作。

爲了實現你的結果,合併要明確地合併字段:

Course c2 = (Course) session.get(Course.class, 1); 
c2.setCategory("social"); 
c2.setRecommendedBook("Modern History"); 
if (c1.getCategory != null) { 
    c2.setCategory(c1.getCategory()); 
} 
if (c1.getRecommendedBook() != null) { 
    c2.setRecommendedBook(c1.getRecommendedBook()); 
} 
... 
+0

感謝答覆。爲什麼hibernate將其命名爲'merge',而不是它可以說'saveDetachedInstance',因爲它沒有做任何合併b/w persisntent實例和detached實例。它只是放棄持久性實例中的更改並保存已分離的實例。我相信方法的名稱是不對的 –

+0

Hibernate沒有選擇這個名字。 JPA規範編寫者選擇了它。我不明白爲什麼「複製除空元素之外的所有字段的值」將會是更好的合併定義。不要責怪Hibernate沒有閱讀你正在使用的方法的文檔。 –