Hibernate懶載入常見問題及解決方案
阿新 • • 發佈:2019-01-06
什麼是懶載入?
懶載入(Load On Demand)是一種獨特而又強大的資料獲取方法,它能夠在使用者滾動頁面的時候自動獲取更多的資料,而新得到的資料不會影響原有資料的顯示,同時最大程度上減少伺服器端的資源耗用。(百度說的)
通俗點,就是在找一個物件時不找出與他關聯的物件,而是在需要相關聯物件(或其屬性)時才去資料庫中找,也稱之為延遲載入。
我們一般通過MyEclipse的逆向工程生成實體類,併為該類自動配置註解,該實體類有一個一對多的屬性,這時hibernate自身提供給我們fetch = FetchType.LAZY這個屬性:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "standard" )
public Set<Courier> getCouriers() {
return this.couriers;
}
從程式碼上可以看到,該註解預設設定了延遲載入fetch = FetchType.LAZY。所以當應用程式查詢該實體類對應的表的資料時,出現了以下錯誤:
org.hibernate.LazyInitializationException:could not initialize proxy - no Session
。。。。。省略。。。。。。
這意味著在讀取資料的時候,Session已經關閉。
解決方案一:把FetchType.LAZY設定為EAGER,取消延遲載入機制。(不推薦)
fetch = FetchType.EAGER
解決方案二:在web.xml中新增一個過濾器,這個過濾器必須要位於Struts的核心過濾器之前
(推薦)
< 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>/*< /url-pattern>
< /filter-mapping>
當然了,如果我們用了Spring整合Hibernate JPA,那麼Session就被EntityManager所替換,這時我們推薦使用Spring框架提供過濾器:OpenEntityManagerInViewFilter
該過濾器作用的是,在訪問檢視層(包括Action層)之前開啟session,在訪問結束之後,關閉session
<!-- 必須放在struts2的過濾器之前 -->
<filter>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>