在開發Struts2.0+hibernate3.2+spring2.5項目過程當中,遇到了failed to lazily initialize a collection of role: XXXXXX, no session or session was closed 這個異常的麻煩,起初到網上找資料,獲得了下面的一些解決方法:web
一、是把對應一對多的那兩個列lazy=true改成lazy=false便可;spring
二、對於查詢中若是用的是xxx.load(class,id)則改成xxx,get(class,id);數據庫
三、在web.xml文件中加入: 網絡
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>session
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>app
<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>post
<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>