剛開始接觸這種數據持久化框架時,使用的是Maybatis,相較于最原始的JDBC+SQL模式,Maybatis簡直就是神器,特別是在用過Maybatis動態SQL后,簡直就開始對Maybatis愛不釋手。后來工作要求,又接觸到了Hibernate,剛入手時,還是很不適應的,感覺這個持久化框架已近偏離傳統的SQL模式,一切都只能重新學習。用過一段時間Hibernate后才發現了它的便利性。
之前問過公司的大佬,為啥要用Maybatis,得到的答案:是出于性能的要求,由于數據量龐大,輕便的Maybatis在性能上表現的更加優異。不過后來,隨著對Hibernate認識的加深,才發現Hibernate在性能上也并沒有落下。比如懶加載就很好的解決了Hibernate性能方面的一些問題。在配置映射時,我們不可能說像Maybatis一樣哪次用什么我們就查什么,Hibernate的映射必須是完整的。所以這就導致了每次Hibernate加載時都會更具映射關系把所有關聯數據查詢出來。但是其中很多可能是我們并不需要的。這就浪費了很多的系統資源,而Hibernate懶加載就很好的解決了這個問題,通過代理的方式,在你查詢一個對象時,Hibernate并不會立馬去查詢數據庫,而是生成一個代理對象,當你要獲取對象的屬性(字段)值時,才會去真正的查詢對象。不得不說這很有效。
但是這種方式也存在一個問題,就是拿到代理對象后,session忽然關閉了,這時再想去執行查詢的時候,就查不到數據了。而且還會拋出org.hibernate.LazyInitializationException。
一般來說這種問題是很容易被發現的,但是有些Hibernate項目經常是使用了AspectJ來進行切面處理的,這就使得LazyInitializationException不那么容易被發現了。可能自己查到了一個對象,傳給了某個方法,之后再來獲取對象的屬性時就報錯了。
知道了原因就很好解決這個問題了,我們只要在原來的回話被結束掉之前把對象的相關屬性拿出來,再去使用,這樣就不會有問題了。或者直接改映射文件的配置(不推薦)。