避免 Hibernate 中用get/load方法獲取的實體呼叫set方法後自動更新
1、問題症狀描述
最近在處理一個新需求問題,程式碼的大致邏輯是獲取一個實體物件,呼叫該物件的set方法設定其中的某些欄位,然後把修改後的實體作為引數供其他地方呼叫,根據返回值來決定是否更新這個實體到資料庫中。
按照這個思路呼叫了系統中的getByid方法,結果測試的時候發現,不管返回值是什麼,這個實體最終都被更新到資料庫中了。好吧,這明顯是有問題的....【沒有問題的程式碼不是好程式碼 - -|| 】
2、問題原因分析和解決辦法
2.1 檢視日誌資訊後發現,系統總是會列印出一個update語句。說明系統的確是執行了更新操作的,但是我並沒有呼叫任何和update相關的方法。
2.2 跟蹤程式碼發現,getById方法其實是呼叫了hibernate的get方法。嗯,果然,問題出在這裡了.....
2.3 Hibernate的get和load方法查詢出的實體都是持久化物件,拿到該物件後,如果你呼叫了該物件的set方法,那麼在事務遞交的時候,Hibernate會把你設定的值自動更新到資料庫中。
解決辦法:
在獲取實體物件後,呼叫下getHibernateTemplate().evict(entity)方法,該方法的作用是把持久化物件變成託管狀態。變成託管狀態後,Hibernate就不會再去自動更新該實體。
3、相關知識擴充套件
Hibernate的幾種實體狀態:
1.瞬態:
一個實體通過new操作符建立後,沒有和Hibernate的Session建立關係,也沒有手動賦值過該實體的持久化標識(持久化標識可以認為是對映表的主鍵)。
此時該實體中任何屬性的更新都不會反映到資料庫表中。
2.持久化:
當一個實體和Hibernate的Session建立了關係,並獲取了持久化標識,而且在Hibernate的Session生命週期記憶體在。
此時針對該實體任何屬性的更改都會直接影響到資料庫表中一條記錄對應欄位的更新,即與資料庫表同步。
3.脫管:
當一個實體和Hibernate的Session建立了關係,並獲取了持久化標識,而此時Hibernate的Session生命週期結束,實體的持久化標識沒有被改動過。
針對該實體任何屬性的修改都不會及時反映到資料庫表中。
關閉session可以使實體從持久化狀態轉為託管狀態。
知識擴充套件部分參考自 http://blog.csdn.net/sunhuwh/article/details/9183539 ,感謝作者。
轉帖請註明文章來源: http://blog.csdn.net/yang_lover/article/details/45057181
相關文章
- 分類不能自動建立 get set 方法
- Hibernate的Session的get()和load()方法區別Session
- java反射呼叫set和get方法的通用類Java反射
- Bean類自動生成判斷null值的Set()和Get()方法BeanNull
- 快速生成get、set方法
- restfulwebservice 呼叫方法 getRESTWeb
- postman自動呼叫獲取tokenPostman
- Android 軟體自動更新功能實現的方法Android
- idea中引入lombok外掛後編譯時實體bean無get/set方法IdeaLombok編譯Bean
- js中用tagname和id獲取元素的3種方法JS
- 修改自動生成get/set方法模板程式碼
- Hibernate get和load區別
- C#在類中用呼叫Form的方法C#ORM
- ubuntu server獲取並自動設定最快映象的方法UbuntuServer
- springmvc 後臺獲取cookie的方法SpringMVCCookie
- 呼叫API介面獲取淘寶商品評論:方法與實戰API
- js獲取元素的方法(獲取html元素的方法)JSHTML
- Idea實體類上加@Data註解但get/set方法不生效Idea
- 區域性方法$(“html”).load()和全域性方法$.get()、$.post()HTML
- +load和+initialize方法呼叫時機
- Hibernate查詢自動更新
- C# 呼叫dll獲取dll物理路徑的方法C#
- Objective-C中get/set方法初探(1)Object
- Objective-C中get/set方法初探(2)Object
- Hibernate中Session.load/get區別Session
- 獲取方法
- 封裝中的get、set方法-學習筆記封裝筆記
- 證明:ThreadLocal的get,set方法無法防止記憶體洩漏thread記憶體
- Hibernate學習(四)get和Load比較
- 介面自動化測試框架--http請求的get、post方法的實現框架HTTP
- 用Certbot 獲取和自動更新SSL證書
- hibernate延遲載入(get和load的區別)
- Apapche獲取真實IP地址方法
- 09 獲取需求的方法
- Android客戶端apk自動檢測更新自動下載自動安裝的實現方法Android客戶端APK
- 如何關閉Mac版Chrome自動更新的方法?MacChrome
- Win10 1909系統關閉自動更新後自動開啟的解決方法Win10
- win10系統設定更新後不提示自動重啟的方法Win10