使用OpenSessionInViewFilter方案解決Hibernate懶加載異常的問題

使用OpenSessionInViewFilter方案解決Hibernate懶加載異常的問題

在項目練習的時候,遇到了這個懶加載異常,當時解決的方法是在配置文件中設置lazy="false"。該方法有很到缺點,效率極低,我們將所有相關聯的數據都查詢了,頻繁的查詢降低了效率!!不建議采用

Web程序中的懶加載異常說明及解決方案

圖一

異常說明

當一個請求來了之后,先執行Action,在執行結果。在action里面有Service業務層,調用Service,Service做業務處理。

開始執行Service方法的時候,開始開啟事務和Session,Service方法結束或回滾提交事務,會自動關閉Session。

在Service里面查詢列表加載對象的時候,但是其相關連的對象并沒有加載,但是Session關閉了,關聯對象最終沒有加載,在頁面中用到了懶加載屬性,但是是在之前加載的,且Session已經關閉了,所以有了懶加載異常,說沒有Session。

解決方案

圖二

從上面的異常說明中可以得知,主要原因是在頁面中沒有Session,那么我們可以使Session不關閉,不關閉Session又會出現問題,那么我們就在整個請求的過程中添加一個過濾器或者攔截器,過濾器或攔截器是先進后出。我們在過濾器或攔截器中關閉Session,也就是在當頁面顯示一些數據后,再在過濾器或攔截器里面關閉Session就可以了。但是需要設置當事務提交之后,不需要關閉Session。在spring中已經有一個過濾器可以幫助我們在過濾器中關閉Session了。OpenSessionInViewFilter

配置方案

第一步:web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1">
    <display-name>OA</display-name>

    <!-- 配置spring的監聽器,用于初始化spring對象 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext*.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- 配置Spring的用于解決懶加載問題的過濾器,一定要配置在Struts2之前 -->
    <filter>
        <filter-name>OpenSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>OpenSessionInViewFilter</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>

    <!-- 配置Struts2的主過濾器 -->
    <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>

</web-app>

注意:攔截的是所有的action,而且在Action里面調用的是Service,與struts的配置Action的擴展名一樣

第二步:struts配置

<!-- 配置擴展名為action -->
<constant name="struts.action.extension" value="action" />
流程圖

不過,當整個系統中出現兩個請求的,并且不是一個請求的時候,還是會出現懶加載異常。比如,一個是SSH框架里面的Struts2里面的請求,里面已經已經通過OpenSessionInViewFilter解決的懶加載異常,但是當系統需要的Servlet的監聽器里面需要初始化某些數據的時候,而且這些數據與其他數據有關系的時候,還是會出現懶加載異常,所以還要在實體配置文件中配置lazy="false"屬性。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容