2013-08-07 103 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

相关问题