7

我正在将 Hibernate 与 JPA 一起使用,并且具有如下所示的关系:

public class PencilImpl implements Pencil {

    @ManyToOne(targetEntity = PersonImpl.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "owner", nullable = false)
    private Person owner;

    ...

    @Override
    public final Person getOwner() {
        return owner;
    }
}

由于我开始使用 LAZY 提取类型,每次我尝试获取铅笔的所有者 ( pencil.getOwner ) 时,我都会得到一个非空对象,该对象的所有内部属性都设置为空。

我看起来像 Hibernate 创建的代理在它应该从数据库中获取真实对象时没有。

有任何想法吗?谢谢 :)

4

2 回答 2

8

这就是 Hibernate 实现延迟加载的简单方法。它会给你一个代理对象而不是你的实体类的一个实例。当你说

一个非 null 对象,它的所有内部属性都设置为 null

这可能是您在调试器中看到的,对吧?您不必担心,一旦您通过代码或通过调试器内部的调用访问这些属性中的任何一个,Hibernate 将在后台从 DB 加载数据,构造实体类的实例和所有调用代理对象将透明地委托给实际实体。所以通常,理想情况下,您不必关心 Hibernate 代理 <-> 实体对象的区别。

无论如何,我可以想到两个原因来意识到这种区别:

  1. 性能:当您在循环中访问延迟加载的集合的元素时,延迟加载确实会降低您的应用程序的速度
  2. 继承:如果您的数据模型使用继承,请非常小心instanceof和强制转换。阅读这个关于如何测试对象是否是 Hibernate 代理以及如何将其转换为真实实体对象的SO 问题
于 2012-01-20T17:38:25.893 回答
2

正如 JB Nizet 所建议的那样,我的类的 getter 中的final修饰符弄乱了 hibernate 为延迟加载关系创建的代理。

于 2012-01-27T18:10:42.337 回答