1. 程式人生 > >SSH:hibernate懶載入導致的no Session

SSH:hibernate懶載入導致的no Session

在hibernate中,我們經常會設定兩個實體之間的關係為

<one-to-one>   <many-to-many> <one to many>

用來描述兩張表之間的關係,如一個員工有多種職務,而一個職務由多個員工擔任,我們在查詢員工的時候,需要顯示其職務.
而我們查詢員工列表會這樣查詢:

hibernateTemplate.find("from User");

這樣就可以查詢到所有的員工的資訊.
但是當我們在頁面呼叫員工的職務屬性的時候,就會發現丟擲了一個異常

could not initialize proxy - no Session

為什麼會出現這個問題呢?
這就要說到hibernate的懶載入機制了.
什麼是懶載入
懶載入就是在你查詢表的時候只會返回一個id,而不會返回其他資訊,這樣做是為了減輕資料庫的壓力,只有當你需要其他資訊(就是當你呼叫了其他屬性,如呼叫了getter方法),這時候hibernate才會再從資料庫中載入其他屬性,要不然除了id,其他屬性都是null.

現在來想想為什麼會丟擲no session錯誤
當你查詢員工的時候,由於員工與職務為多對多關係,所以查詢得到的員工列表中,職務只有id屬性,其他屬性為null.當你在頁面中呼叫員工的職務屬性的時候,hibernate才會從資料庫查詢.
但是…由於hibernateTemplate是spring所管理的,spring會在你的方法結束之後,自動釋放session資源,就是說當你在Dao層返回員工列表之後,session就被釋放了.當頁面呼叫了員工中的職務屬性的時候,hibernate想去資料庫查詢,但是,由於session已經被關閉了,所以才會丟擲no session錯誤

解決辦法
在web,xml中配置,延遲session的關閉

<!--spring 過濾器,延遲session關閉-->
  <filter>
        <filter-name>openSession</filter-name>
        <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>openSession</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

值得注意的是這個過濾器一定要放在struts2核心過濾器之前