JPA / Hibernate代理不提取实际对象数据,将所有属性设置为null

时间:2012-01-20 17:24:52

标签: java hibernate jpa javassist

我正在使用带有JPA的Hibernate并且具有如下所示的关系:

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 fetch类型,每次我尝试获取铅笔的所有者( pencil.getOwner )时,我会得到一个非null对象,其所有内部属性都设置为null。

我看起来Hibernate创建的代理不应该从数据库中获取真实对象。

有什么想法吗?谢谢:))

2 个答案:

答案 0 :(得分:6)

这就是Hibernate如何实现延迟加载。它将为您提供代理对象,而不是实体类的实例。当你说

  

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

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

无论如何,我可以想出两个理由来了解这种区别:

  1. 性能:当您在循环中访问延迟加载的集合的元素时,延迟加载可能会真正减慢您的应用程序
  2. 继承:如果您的数据模型使用继承,请对instanceof和强制转换非常小心。阅读this SO question,了解如何测试对象是否是Hibernate代理以及如何将其转换为真实实体对象

答案 1 :(得分:2)

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