0

据我了解,即使在使用 getter 方法后,JPA 中的lazyLoadedObject 也可能不会加载。因此在下面的示例中,在笔画 1 之后,lazilyLoadededPerson 可能仍然为空,并且只有在笔画 2 之后,容器才会对数据库运行查询。

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 也会为空。当实体存在于数据库中但永远不会调用 getName() 方法时,我们会遇到这种情况。

4

1 回答 1

2

简短的回答

延迟加载的对象永远不会为空。

更长的答案

该解释对Hibernate有效,但其他 JPA 提供程序应该类似。有关延迟加载如何工作的详细说明,请参阅官方文档,或查看这篇简短的文章。但核心事实是:

如果出于某种原因或另一个Hibernate决定延迟加载一个对象,那么您不会得到您想要的对象,而是该对象的代理(即不是-reference null)。只要您在该代理上调用只能通过访问数据库才能知道的某些内容,该代理就会执行此操作。如果您有一个活动会话(并且满足其他一些条件),Hibernate会执行必要的查询并返回调用。

你的例子

让我们以您的示例为例,并通过声明对其进行扩展

MyPerson lazilyLoadedPerson = runQueryToLoadPerson(); 
if (lazilyLoadedPerson != null) { //if lazilyLoadedPerson == null suppose that such person doesn't exists in database
    return lazilyLoadedPerson.getName(); 
}

假设您没有为 class 定义代理类MyPersonHibernate没有其他选择,只能从数据库中实际加载您想要的对象。原因之一正是您正在做的事情:如果它会返回null,您无法检查该对象是否甚至存在于数据库中。

建议

一开始担心延迟加载可能会让人感到困惑。我的建议是,不要太早这样做。如果您刚刚了解 JPA,只需使用所有 Collections 注释fetch = FetchType.EAGER而不定义任何代理,您将永远不会遇到延迟加载。

如果您更好地了解整个概念,您可以阅读延迟加载并相应地更改您的xml文件或注释。

于 2013-06-28T14:18:15.943 回答