org.hibernate.LazyInitializationException: failed to lazily initialize


今天搞了一上午,都在解決這個問題:org.hibernate.LazyInitializationException: failed to lazily initialize

原因很簡單,是在非法的session中去調用lazy=“true“的屬性,

網上資料蠻多的,解決方法有兩個

1,把lazy=”false“

2,在web.xml中加入:(在structs的過濾器之前)

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<!-- 加入上面這些 -->
<filter> 
        <filter-name>struts2</filter-name>  
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  </filter>  
  <filter-mapping>  
      <filter-name>struts2</filter-name>  
      <url-pattern>/*</url-pattern>  
  </filter-mapping> 

第一種方法,就是設置為不要用lazy加載元素,這樣做,雖然可以解決上面這個問題,但是會產生一些不必要的開銷。比較復雜的對象對應關系,或者數據量比較大的時候,不推薦這么做
第二種方法,就是避免session關閉過早導致出現這樣的異常,這樣的方法以前也是使用過,而且一般情況下filter過濾鏈接都會做。

 

但是以上這兩種方法,在解決小規模的數據時 ,還湊活能用,但是在大量數據時 ,就會產生大量的耗時。

下面說說,我遇到的問題吧,先說前提:

有員工Staff和所在部門Group兩個對象,他們是many-to-many的關系,一個員工可以在多個部門中(比如,甲可以是銷售部門的,也可以同時是人事部門的);一個小組里面有多個員工,如果采用上面兩種解法,就會導致下面這樣的事情發生:

當我在查詢 Staff 甲 時,會再查詢 甲所在的部門A,B,C,D,因為之前設置的兩種方法,會在我們實例化一個對象的時候,將其中lazy加載的所有元素都實例化,也就是會造成,系統會去實例化A,B,C,D部門下的所有員工,這些員工又在別的一些部門中,依次直至所有的對象都被實例化出來,導致相當的耗時。

(不要問我為什么知道,說多了,都是淚啊!!)

 

最后經過排查,發現是因為兩句log ,也就是我在獲取對象后,用了一句

System.out.println("staff="+staff);

當系統執行這么一句的時候,是會去實例化staff對象里面的所有元素,但是因為staff里面的group是lazy加載的,所以,此時才會出現之前提到過的這個exception.

所以,記住,有lazy加載的對象時,千萬不能用=這個操作,不然必報這個exception

 

 

 


免責聲明!

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



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