2010-12-22 88 views
107

Hibernate中persist()和merge()之間的區別是什麼?Hibernate中persist()和merge()之間的區別是什麼?

persist()可以創建一個UPDATE & INSERT查詢,例如:

Hibernate: insert into A (NAME, ID) values (?, ?) 
Hibernate: update A set NAME=? where ID=? 

所以persist()方法可以產生一個Insert:

SessionFactory sef = cfg.buildSessionFactory(); 
Session session = sef.openSession(); 
A a=new A(); 
session.persist(a); 
a.setName("Mario"); 
session.flush(); 
在這種情況下 查詢將這樣生成

和更新。

現在用merge()

SessionFactory sef = cfg.buildSessionFactory(); 
Session session = sef.openSession(); 
Singer singer = new Singer(); 
singer.setName("Luciano Pavarotti"); 
session.merge(singer); 
session.flush(); 

這是我在數據庫中看到:

SINGER_ID SINGER_NAME 
1   Ricky Martin 
2   Madonna 
3   Elvis Presley 
4   Luciano Pavarotti 

現在使用merge()

SessionFactory sef = cfg.buildSessionFactory(); 
Session session = sef.openSession(); 
Singer singer = new Singer(); 
singer.setId(2); 
singer.setName("Luciano Pavarotti"); 
session.merge(singer); 
session.flush(); 

這是我看到更新記錄數據庫:

SINGER_ID SINGER_NAME 
1   Ricky Martin 
2   Luciano Pavarotti 
3   Elvis Presley 
+7

javadoc對於他們做什麼以及它們之間的區別是非常明確的。你有沒有閱讀和理解它? – skaffman 2010-12-22 12:24:40

+1

檢查http://stackoverflow.com/questions/161224/what-are-the-differences-between-the-different-saving-methods-in-hibernate – 2010-12-22 12:25:59

+0

http://stackoverflow.com/questions/1069992/jpa- entitymanager-why-use-persist-over-merge – Bozho 2012-10-12 13:53:06

回答

136

JPA specification包含這些操作的語義的非常精確的描述,除了在Javadoc更好:

的語義堅持 操作中,施加到一個實體X是 如下:

  • 如果X是一個新實體,則它將被管理。實體X將在 事務提交或 刷新操作的結果 或之前輸入到數據庫中。

  • 如果X是一個 先前存在的被管實體,則它被 忽略的持久操作。 然而,持續操作是 級聯到由X, 引用的實體,如果從X到這些 其他實體的關係被註釋與 cascade=PERSISTcascade=ALL 註釋元素值或與該等效XML描述 元素指定 。

  • 如果X是已刪除的實體,則它將變爲管理的,即 。

  • 如果X是一個 分離對象,所述 EntityExistsException可能拋出 操作被調用時,仍然存在, 或EntityExistsException或 另一個PersistenceException可以 在沖洗拋出或提交時間。

  • 對於 通過從X一 關係引用,如果 關係爲Y已經被註釋 與級聯元件值的所有實體ý cascade=PERSISTcascade=ALL,所述 persist操作被施加到Y


的semant是合併應用到實體X操作 的集成電路如下:

  • 如果X是一個分離的實體,X的 被複制到的預先存在的 管實體實例X」的狀態創建相同的 標識或X 的新託管副本X'。

  • 如果X是一個新的實體 例如,一個新的管理實體 例如X「創建和X的狀態 被複制到新的託管 實體實例X」。

  • 如果X是一個 除去實體實例,一個 IllegalArgumentException將由合併操作來 拋出(或 事務提交將失敗)。

  • 如果X 是一個管理實體,它是由 合併操作忽略,然而, 合併操作級聯到由X的關係 引用 實體,如果這些關係 被註釋與級聯 元素值cascade=MERGEcascade=ALL註釋。

  • 對於所有 實體Y上從X具有級聯元件 值cascade=MERGEcascade=ALL關係 引用,Y 被遞歸合併爲Y」。對於由X引用的所有 這樣的Y,將X'設置爲 引用Y'。 (注意,如果X是 管理,則X是相同的對象 X「)

  • 如果X是一個實體合併到X」, 與另一個實體Y, 其中cascade=MERGEcascade=ALL是基準 未指定,然後從X 相同的關聯的導航「產生一個 參照管理對象Y」與 相同持久標識爲Y.

13

這是來自JPA。在一個非常簡單的方法:

堅持(實體)應與全新的實體使用,將它們添加到數據庫(如果實體在DB已經存在會有EntityExistsException擲)。

應該使用合併(實體),如果實體被分離並被更改,則將實體放回持久化上下文。