首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring + Hibernate 解決 LazyInitializationException:OpenSessionInViewFilter 一鍵修復

     編輯:Java 相關知識

問題根源

Hibernate 延遲加載要求 Session 開啟狀態。典型場景:Service 事務結束關閉 Session,Controller 轉發到 JSP 視圖渲染時觸發關聯屬性訪問,拋出 LazyInitializationException: could not initialize proxy - no Session。

標準解決方案:OpenSessionInViewFilter

Spring 提供 org.springframework.orm.hibernate3.support.OpenSessionInViewFilter,將 Session 綁定到整個 HTTP 請求週期,請求結束再關閉,確保視圖層可安全延遲加載。

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>true</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>hibernateFilter</filter-name>
  <url-pattern>*.do</url-pattern>
</filter-mapping>

關鍵參數說明

  • singleSession=true:請求範圍內複用同一 Session,避免多個 Session 導致實例不一致
  • url-pattern:建議匹配所有進入 Controller 的路徑(如 *.do、/app/*),不要攔截靜態資源

原理流程

  1. 請求進入 → Filter doFilterInternal 開啟 Session 綁定到 ThreadLocal
  2. Controller 執行 → Service 事務使用同一 Session
  3. 視圖渲染 → JSP/Velocity 訪問關聯屬性,觸發延遲加載,Session 仍開啟
  4. 請求結束 → Filter 關閉 Session、清理 ThreadLocal

注意事項與最佳實踐

  1. 事務邊界清晰:@Transactional 方法仍負責提交/回滾,Filter 僅管理 Session 生命週期
  2. 避免長事務:Session 持有至請求結束,大量數據讀取可能導致內存壓力,必要時在 Service 手動 session.clear()
  3. 只讀優化:查詢頁面可配合 @Transactional(readOnly=true) 降低資料庫鎖開銷
  4. 替代方案:Hibernate 3.1+ 支援 hibernate.enable_lazy_load_no_trans 屬性,但不推薦長期依賴,掩蓋設計問題

來源參考

原文:springking - Spring+Hibernate 避免延遲加載異常

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved