Hibernate: merge方法


在Hibernate中,有save、persist、savaOrUpdate、merge等方法有插入數據的功能。前三者理解起來較后者容易一些,merge方法從api中的介紹就看以看出它是最復雜的。下面是Hibernateapi中的原文:

merge
Object merge(Object object)
             throws HibernateException
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge".
The semantics of this method are defined by JSR-220.
Parameters:
object - a detached instance with state to be copied
Returns:
an updated persistent instance
Throws:
HibernateException

首先從參數說明來看,merge的參數應該是一個處於托管狀態的實例對象,而返回值則是一個持久化對象。但是這里的參數並不是一定要是托管狀態的對象,它還可以是瞬態和持久化的實例對象。正因如此,才使merge方法變得復雜化。

經代碼檢驗從merge方法產生的效果來看,它和saveOrUpdate方法相似,因此雖然上面提到是因為參數狀態的不同造成復雜化,但是這里我並不打算分參數的不同狀態來理解merge,而是根據參數有無id或id是否已經存在來理解merge。個人認為這樣更容易理解,而且從執行他們兩個方法而產生的sql語句來看是一樣的。

1. 參數實例對象沒有提供id或提供的id在數據庫中不存在:這時merge將執行插入操作,產生的sql語句如下,       

          Hibernate: select max(uid) from user     

          Hibernate: insert into hibernate1.user (name, age, uid) values (?, ?, ?)

2. 參數實例對象的id在數據庫中已經存在,此時又有兩種情況:

(1)如果對象有改動,則執行更新操作,產生sql語句有,

         Hibernate: select user0_.uid as uid0_0_, user0_.name as name0_0_, user0_.age as age0_0_ from hibernate1.user user0_ where user0_.uid=?
         Hibernate: update hibernate1.user set name=?, age=? where uid=?

(2)如果對象為改動,則執行查詢操作,產生的語句有,

         Hibernate: select user0_.uid as uid0_0_, user0_.name as name0_0_, user0_.age as age0_0_ from hibernate1.user user0_ where user0_.uid=?

不管哪種情況,merge的返回值都是一個持久化的實例對象,但對於參數而言不會改變它的狀態。

雖然從功能上merge方法與saveOrUpdate類似,但他們仍有區別。現在有這樣一種情況:我們先通過session的get方法得到一個對象u,然后關掉session,再打開一個session並執行saveOrUpdate(u)。此時我們可以看到拋出異常:Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session,即在session緩存中不允許有兩個id相同的對象。不過若使用merge方法則不會異常,其實從merge的中文意思(合並)我們就可以理解了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM