据我所知,即使使用了getter方法,JPA中的lazyLoadedObject也可能无法加载。因此,在下面的示例中,在笔划1之后,lazilyLoadededPerson可能仍为null,并且只有在笔划2之后,容器才会将查询运行到db。
lazilyLoadedPerson = runQueryToLoadPerson();
lazilyLoadedPerson.getName();
我的问题是 :以下代码是否包含笔划2中的错误?
lazilyLoadedPerson = runQueryToLoadPerson();
if (lazilyLoadedPerson != null) { //if lazilyLoadedPerson == null suppose that such person doesn't exists in database
return lazilyLoadedPerson.getName();
}
为什么我认为这将是一个错误: 在上面的例子中的笔划1之后,即使数据库中存在lazilyLoadedPerson,lazilyLoadedPerson也将为null。我们遇到实体存在于数据库中但不会调用getName()方法的情况。
答案 0 :(得分:2)
延迟加载的对象从不 null。
该解释适用于 Hibernate ,但其他JPA提供程序应该类似。有关延迟加载如何工作的详细说明,请参阅the official documentation,或查看简短加载的this short article。但核心事实是:
如果由于某种原因 Hibernate 决定懒惰地加载一个对象,你不会得到你想要的对象而是代替那个对象(即不 null
- 参考)。只要您在该代理上调用只能通过访问数据库来识别的内容,代理就会这样做。如果您有活动会话(并且满足一些其他条件), Hibernate 将执行必要的查询并返回调用。
让我们举个例子并用声明扩展它
MyPerson lazilyLoadedPerson = runQueryToLoadPerson();
if (lazilyLoadedPerson != null) { //if lazilyLoadedPerson == null suppose that such person doesn't exists in database
return lazilyLoadedPerson.getName();
}
假设您没有为类MyPerson
定义代理类, Hibernate 没有其他选项,只能从数据库中实际加载您想要的对象。其中一个原因正是您正在做的事情:如果它将返回null
,您无法检查该对象是否存在于数据库中。
担心延迟加载在开始时可能会非常混乱。我的建议是,不要太早这样做。如果您刚刚了解JPA,只需使用fetch = FetchType.EAGER
注释所有集合,并且不定义任何代理,您将永远不会遇到延迟加载。
如果您更了解整个概念,可以阅读延迟加载并相应地更改 xml 文件或注释。