简单的Hibernate / JPA查询返回代理对象

时间:2017-03-27 15:23:20

标签: java hibernate jpa spring-data spring-data-jpa

我正在使用Hibernate 5&春季数据。 在PartyDao内,我有以下方法:

@Query("from Party where id in :partyIDs")
List<PartyTO> loadByIDs(@Param("partyIDs") List<Long> partyIDs);

我这样称呼它:

partyList = partyDao.loadByIDs(userPartyIDsList));

但是我得到了一个Hibernate代理对象列表(所有字段都设置为nullhandler字段为org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer

这对我没有意义!为什么Hibernate没有加载 FROM查询根目录我指定的对象?

我把它改为:

@Query("select party from Party party where party.id in :partyIDs")
List<PartyTO> loadByIDs(@Param("partyIDs") List<Long> partyIDs);

尝试更明确地说明我想要对象获取,但它仍然返回代理对象。有什么我想念的吗?我不知道如何让它自己取得。

修改 代理对象实际上有一个名为target的属性,它具有所有属性集。为什么不将它们放入物体本身?

我没有得到&#34;延迟初始化异常&#34;,但NullPointerException内的Comparator正在按名称对各方进行排序:

...
return o1.name.compareTo(o2.name);

2 个答案:

答案 0 :(得分:2)

问题是您可以直接访问对象的name属性。

    ...
    return o1.name.compareTo(o2.name);

Hibernate将始终返回代理对象,并且一些更复杂的结构的序列化可能会导致您将来遇到问题,包括提到的惰性实例化异常。但是,问题的原因是直接访问属性,如果您在比较器中正确使用了getter函数,则不会出现任何其他问题。

代理对象是目标类的运行时扩展,它将具有与目标类相同的接口,但在真正的OOD方式中,内部不可见或不可访问。唯一的保证是提供的接口合同,无论您的对象是什么,都应该编码。

更改您的比较器和其他代码以符合以下条件,您再也不会遇到此问题。

    ...
    return o1.getName().compareTo(o2.getName());

答案 1 :(得分:1)

通过调用property方法而不是属性本身,将值读入主对象。

必须将Comparator return语句更改为:

return o1.getName().compareTo(o2.getName());