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

jua*_*edi 7 java hibernate jpa javassist

我正在使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

有任何想法吗?谢谢 :)

Rob*_*ier 6

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

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

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

无论如何,我可以想到有两个理由要注意这种区别:

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

  • 谢谢罗伯特.这里的问题是代理实际上没有做它应该做的事情.对代理的getter的调用返回null. (4认同)

jua*_*edi 2

正如 JB Nizet 所建议的,我的类的 getter 中的最后一个修饰符会扰乱 hibernate 为延迟加载关系创建的代理。