我对JPA 2.0,Hibernate和“orphanRemoval”有疑问。
首先我的设置:
我有两个相当简单的实体类,“用户”和“AvatarImage”,一个“用户”有一个“AvatarImage”,因此在“用户”和“AvatarImage”之间存在关系。
在“用户”类中,属性如下所示:
// class "User"
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true)
private AvatarImage avatarImage;
因此,这意味着,如果将“avatarImage”属性设置为null,则将删除“用户”和“AvatarImage”之间的引用,并且“orphanRemoval”机制将从数据库中删除“avatarImage”(如果我输入错误,请更正我)。
因此,当我为某个用户更新“avatarImage”时,当前必须编写以下代码:
user.setAvatarImage( null ); // First set it to null
userRepository.save( user ); // Now "orphanRemoval" will delete the old one
user.setAvatarImage( theNewAvatarImage );
userRepository.save( user );
因此,首先将“avatarImage”属性设置为null,保存“用户”,然后将新的AvatarImage设置为“theNewAvatarImage”,再次保存用户。
这是目前对我有效的唯一方法-“orphanRemoval”将设置为“null”时删除旧的“avatarImage”,然后保存用户。
但是,我本以为该代码也可以工作:
user.setAvatarImage( theNewAvatarImage );
userRepository.save( user );
因此,我忽略了将“avatarImage”设置为“null”,而只是设置“theNewAvatarImage”,替换了旧的“avatarImage”。但这是行不通的,在提交事务后,旧的AvatarImage不会从数据库中删除。
有谁知道,为什么第二个代码(只是替换AvatarImage而不先将其设置为“null”)不起作用?
我非常感谢您可以提供的任何帮助
非常感谢!
最佳答案
这与Hibernate JIRA票证HHH-5559和HHH-6484有关。总的来说,从今天开始,Hibernate要求您将引用设置为null并刷新持久性上下文,然后再为该关系提供新的值(请参见HHH-6484中的测试用例);只有在这种情况下,Hibernate才会发出SQL DELETE
语句,从而为orphanRemoval
提供损坏的实现(IMHO)。
简而言之,您将需要等待错误修复,或者编写代码以使引用无效并刷新持久性上下文,或者使用以这种方式支持orphanRemoval
的JPA提供程序(EclipseLink 2.3.0可以)。