我们目前在我们的应用程序中使用Hibernate 5.1,并且我们在很多地方都有懒惰的OnyToOne关系。在getter方法中,我们取消代理实体,以便调用者/客户端不必关心对象本身的不兼容。事实上,它是一个非常好的解决方案,因为在一个中心位置进行unproxying,并且调用者不会忘记解除代理。调用者通常在实体上执行instanceof或调用.getClass(),这意味着它必须是无法正常工作的。
这就是这种吸气剂的样子:
@OneToOne(cascade=CascadeType.ALL, orphanRemoval=true, fetch=FetchType.LAZY)
@JoinColumn(name="ContractAgreementId")
public ContractAgreement getContractAgreement() {
return ORMUtils.initializeAndUnproxy(contractArgreement);
}
initializeAndUnproxy()方法基本上是这样做的:
Hibernate.initialize(entity);
return (T)((HibernateProxy)entity).getHibernateLazyInitializer().getImplementation();
这在Hibernate 5.1之前完美运行,但是当我们尝试升级到5.2时,我们发现它的行为与之前有点不同。如果像上面的示例中那样使用级联类型ALL,Hibernate会尝试在会话结束时删除相关实体(上例中的contractArgreement),尽管实体上没有完成更新(只需从中加载父实体)实体经理足以遇到这个问题)。 我的猜测是这样做是因为Hibernate在调用getter时找不到相同的对象(他的代理),而是找到一个不同的对象(unproxied对象)。所以它认为必须从数据库中删除该对象。 我希望你知道我的意思。 Hibernate认为关系已更新(由不同的对象替换),事实上并非如此;它只是没有成功。
我的问题是,这是Hibernate 5.2中的故意行为,还是Hibernate(如5.1或更早版本)认识到对象在发现未经代理的对象而不是代理时没有改变? 如果这是故意的行为,是否有一种不同的方式在getter中进行unproxying而不会遇到这个问题?