Hibernate的merge與update方法的區別

今天做了個測試,寫了個測試用例來看看merge與update時控制檯打印出來的日誌有什麼不一樣。實體bean很簡單,就id和name兩個字段,接下來分別給出以下幾種測試情形的控制檯日誌內容:

1. 數據庫記錄已存在,更改person的name爲一個新的name。

merge方法打印出的日誌如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
Hibernate: update person set name=? where id=?

update方法打印出的日誌如下:
Hibernate: update person set name=? where id=?

2. 數據庫記錄已存在,更改person的name和數據庫裏對應id記錄的name一樣的值。

merge方法打印出的日誌如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
此處相對於第一種情形少了update的動作

update方法打印出的日誌如下:
Hibernate: update person set name=? where id=?

3. 數據庫記錄不存在時,也就是你傳的實體bean的ID在數據庫沒有對應的記錄。

merge方法打印出的日誌如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
Hibernate: insert into person (name) values (?)
如果沒有對應的記錄,merge會把該記錄當作新的記錄來插入。此處我很疑惑,因爲我傳得person實體對象裏寫明瞭id值的,它爲什麼還會做插入的動作呢?

update方法打印出的日誌如下:
Hibernate: update person set name=? where id=?
2009-11-22 20:59:55,359 ERROR [org.hibernate.jdbc.AbstractBatcher] - Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

以下的內容摘抄自網上:
  當我們使用update的時候,執行完成後,我們提供的對象A的狀態變成持久化狀態。
  但當我們使用merge的時候,執行完成,我們提供的對象A還是脫管狀態,hibernate或者new了一個B,或者檢索到 一個持久對象B,並把我們提供的對象A的所有的值拷貝到這個B,執行完成後B是持久狀態,而我們提供的A還是託管狀態。

 

 

merge(oldObj) 操作如下:

if(oldObj沒有id) {
   添加操作
} else {
   if(根據oldObj.id在Hibernate Context中沒有找到對象) {
       加載得到newObj;
        if(newObj == null) {
          添加操作
       }
   }else{
       newObj
   }
  
   if(oldObj裏面的屬性 和newObj不一致) {
      更新操作
   }
  

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章