我发现了hibernate程序的奇怪情况。这是我的代码
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有多个AnotherClass)
指向返回sc.getAnotherClassSet()
作为空指针的异常消息。我确信我的数据库里有这些数据。
我发现,如果我在return sc.getAnotherClassSet()
之前添加System.out.println(sc.getAnotherClassSet())
,我的代码就可以正常工作了。
知道发生了什么事吗?谢谢
可能,您的@OneToMany
关联映射为fetchType="lazy"
(可能是默认情况)。这意味着在加载实体SomeClass
时,关联(在您的情况下为AnotherClassSet
)不会被加载。只有当您尝试使用getAnotherClassSet()
访问它时,才会加载它。
但是,在您的示例中,此方法(getAnotherClassSet()
)是在会话关闭后在return
语句上调用的。
为了解决这个问题,您可以尝试在关闭会话之前调用getAnotherClassSet()
,只是为了加载AnotherClassSet
关联。
因为,您使用的是lazy initialization
(这是默认设置)。在lazy initialization
中,每个集合字段仅在请求时提取。您必须将初始化指定为eager
,代码才能工作。Eager initialization
在一次提取中提取整个对象。