標籤:
failed to lazily initialize a collection of role
在開發Struts2.0+hibernate3.2+spring2.5項目過程中,遇到了failed to lazily initialize a collection of role: XXXXXX, no session or session was closed 這個異常的麻煩,起初到網上找資料,得到了下面的一些解決方案:
1、是把對應一對多的那兩個列lazy=true改為lazy=false即可;
2、對於查詢中如果用的是xxx.load(class,id)則改為xxx,get(class,id);
3、在web.xml檔案中加入:
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>
<!--這個-- <init-param>一定要加不然很可能會報錯: org.springframework.dao.InvalidDataAccessApiUsageException:Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove ‘readOnly‘ marker from transaction definition
-->
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.mmg</url-pattern>
</filter-mapping>
對以上方法進行一一測試,到後來結果都是一樣,出現同樣的異常,後來有苦苦在網上找資料,並自己努力思考,後來也瞭解到spring能很好地解決這個問題, Spring 架構為 Hibernate 消極式載入與 DAO 模式的整合提供了一種方便的解決方案。對那些不熟悉 Spring與 Hibernate 整合使用的人,我不會在這裡討論過多的細節,但是我建議你去瞭解 Hibernate 與 Spring 整合的資料訪問。以一個Web 應用為例, Spring 提供了 OpenSessionInViewFilter 和 OpenSessionInViewInterceptor 。我們可以隨意選擇一個類來實現相同的功能。兩種方法唯一的不同就在於 interceptor 在 Spring 容器中運行並被配置在 web 應用的上下文中,而 Filter 在 Spring之前運行並被配置在 web.xml 中。不管用哪個,他們都在請求將當前會話與當前(資料庫)線程綁定時開啟 Hibernate 會話。一旦已綁定到線程,這個開啟了的 Hibernate 會話可以在 DAO 實作類別中透明地使用。這個會話會為消極式載入資料庫中值對象的視圖保持開啟狀態。一旦這個邏輯視圖完成了, Hibernate 會話會在 Filter 的 doFilter 方法或者 Interceptor 的 postHandle 方法中被關閉。用spring解決這個問題 而且不用把lazy設定為false,提高效能。
方法是:在web.xml中加入以下配置:
<filter>
<filter-name>hibernateFilter</filter -name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
開始時,把這個配置隨意地加到web.xml的最後,發現還是不行,後來又通過網路瞭解到是過濾器順序的問題,應該是:
OpenSessionInViewFilter
ActionContextCleanUp
FilterDispatcher
的順序,最後調整過濾器的順序,一些問題解決。
注意:有些時候會出現一些頁面或者一些其他的action過濾不到,可以修改如下:
<url-pattern>/*</url-pattern>
failed to lazily initialize a collection of role: