2013-08-07 101 views
3

我發現我的休眠程序奇怪的條件。這裏是我的代碼休眠 - 未能懶洋洋地初始化 - 沒有會話或會話關閉

public Set<AnotherClass> getAnotherClassSetsFromSomeClass() { 
     Session session = HIbernateUtil.getSessionFactory().openSession(); 
     Transaction trans = session.beginTransaction(); 
     SomeClass sc = (SomeClass)session.get(SomeClass.class,"classId"); 
     trans.commit(); 
     session.close; 
     return sc.getAnotherClassSet(); 
    } 

這段代碼看起來很好,如果我在Java控制檯上運行它。

,如果我用它一個Web應用程序(JSF),我得到這個錯誤

未能懶洋洋地初始化 - 沒有會話或會話關閉

它具有一對多的關係(一個SomeClass有許多其他類)

指向的異常消息返回sc.getAnotherClassSet()作爲空指針。我敢肯定,我的數據庫中有這些數據。

那麼我發現,如果我加System.out.println(sc.getAnotherClassSet()) berfore return sc.getAnotherClassSet()我的代碼工作正常。

任何想法發生了什麼?謝謝。

回答

5

可能您的@OneToMany關聯映射爲fetchType="lazy"(也許是默認情況下)。這意味着在加載實體SomeClass時,關聯在您的案例AnotherClassSet中未加載。只有當您嘗試訪問它時,它纔會被加載,使用getAnotherClassSet()

但是,在您的示例中,會話關閉後,此方法(getAnotherClassSet())在return統計資料上被調用。

要解決此問題,您可以嘗試在關閉會話之前調用getAnotherClassSet(),以加載AnotherClassSet關聯。

+0

這是答案,而是調用getter或setter,最好對某個函數使用class屬性,如getAnotherClassSet()。size(),並將其加載到SomeClass中的AnotherClassSet。謝謝 –

+0

是的,加載'AnotherClassSet'關聯('SomeClass')是我試圖在我的答案的最後一段中提出的建議;-) – Crferreira

1

因爲,您正在使用lazy initialization(這是默認設置)。在lazy initialization中,每個收集字段僅在請求時被提取。您必須指定初始化爲eager,以使代碼正常工作。 Eager initialization在單個提取中提取整個對象。

+0

你能解釋爲什麼如果我回來之前添加System.out.println(),我的代碼工作? –

+0

關閉會話後,即'session.close()',你不能獲取任何東西。 – user2550754

相關問題