JPA:懒加载光滑的时刻

时间:2013-06-28 10:00:49

标签: java jpa persistence lazy-loading

据我所知,即使使用了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()方法的情况。

1 个答案:

答案 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 文件或注释。