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

Hibernate 延遲加載異常原因與 OpenSessionInViewFilter 解決方案

     編輯:Java 相關知識

什麼是延遲加載

延遲加載即懶加載:關聯對象(如 @OneToMany 集合)在首次訪問時才發起 SQL 查詢,而非加載主對象時即刻加載。適用於數據量大、不常訪問關聯的場景,減少內存佔用與並發壓力。

典型異常場景

// Service 層
Grade grade = gradeDao.findById(1);  // 事務結束,Session 關閉
// 視圖層 (JSP/Thymeleaf)
for (Student s : grade.getStudents()) {  // 拋出 LazyInitializationException
    out.println(s.getName());
}

異常信息:failed to lazily initialize a collection of role: ... no session or session was closed。

解決方案:OpenSessionInViewFilter

在 web.xml 中配置 Spring 提供的過濾器,將 Session 生命周期延長至整個 HTTP 請求結束:

<filter>
  <filter-name>openSessionInView</filter-name>
  <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>openSessionInView</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

注意:Hibernate 5.x 包路徑為 org.springframework.orm.hibernate5,4.x 為 hibernate4,3.x 為 hibernate3。

原理與權衡

  • 優點:視圖層可自由導航關聯對象,代碼簡潔。
  • 缺點:Session 持有時間變長,可能增加數據庫連接佔用;若視圖層觸發大量懶加載,產生 N+1 查詢性能問題。
  • 替代方案:在 Service 層使用 Hibernate.initialize(proxy) 或 FETCH JOIN 顯式預加載所需關聯。

最佳實踐建議

  1. 僅在讀多寫少、關聯導航簡單的頁面啟用 OSIV。
  2. 核心業務查詢採用 DTO 投影或 @EntityGraph 精確控制加載範圍。
  3. 監控 SQL 數量與執行時間,避免隱性 N+1 問題。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved