背景:
Account 和 Group 兩個對象,設置了雙向的many-to-many關係,lazy=true
不使用open session in view 模式
不使用hibernate二級緩存
測試邏輯:
從數據庫獲取一個account對象(存在兩個group: 1.administrators, 2.engineers)
修改這個對象的group信息爲:1.invalid, 2.any one
然後調用DAO的update方法(這部分代碼如下所示)
代碼 v1 只使用merge()
輸出結果:
注意:沒有update/insert/delete語句出現
代碼 v2 只使用update()
輸出結果:
注意:出現了一句update, 一句delete,兩句insert
代碼 v3 先執行update(),再執行merge()
輸出結果:
注意:
1. update/delete/insert語句依然被執行
2. 由於代碼中添加了對group(id=1)的查找,出現了兩句select來查找group表,而不是一句sql通過left outer join來完成
如果把修改前後的accout都調整爲有3個group,結果不確定:
出現過兩種情況:
一條對group表的select,另外一句select還是會使用left outer join
三條對group表的select語句
在代碼v1中也有同樣的效果,同樣的調整,測試結果都是一句select group,一句left outer join,但還不能認爲是100%如此,猜測跟account是否已經被關聯到session有關。
結論:
1. merge()方法,會根據根據對象是否進行了實質性修改,來決定是否執行相應的update/delete/update語句,而upate()則不會進行比較,只用給定的對象信息覆蓋原有信息
參考:
Hibernate Session.merge() javadoc
open session in view 模式