我对JPA 2.0, Hibernate和"orphanRemoval"有疑问。
首先我的设置:
- Spring 3.0.5.RELEASE
- SprnigData JPA 1.0.1.RELEASE Hibernate 3.5.2-Final 数据库:PostgreSQL 9.0
我有两个相当简单的实体类,"User"one_answers"AvatarImage",一个"User"有一个"AvatarImage",所以在"User"one_answers"AvatarImage"之间有关系。
在"User"类中,属性是这样的:
// class "User"
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true)
private AvatarImage avatarImage;
所以这意味着,如果"avatarImage"属性被设置为null,"User"one_answers"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,保存"user",然后将新avatarImage设置为"theNewAvatarImage",再次保存user。
这是唯一的方式,它目前为我工作-"孤儿院移除"将删除旧的"avatarImage"设置为"null",然后保存用户。
但是,我认为这段代码也应该工作:
user.setAvatarImage( theNewAvatarImage );
userRepository.save( user );
所以我省略了设置"avatarImage"为"null",而只是设置"theNewAvatarImage",取代旧的"avatarImage"。但是这不起作用,在事务提交时,旧的AvatarImage不会从数据库中删除。
有没有人知道,为什么第二个代码(只是替换AvatarImage而不将其设置为"空"之前)不工作?
我真的很感激你能提供的任何帮助
非常感谢!
这与Hibernate JIRA票据HHH-5559和HHH-6484有关。总的来说,到目前为止,Hibernate要求您在为关系提供新值之前将引用设置为null并刷新持久性上下文(参见hh -6484中的测试用例);只有在这种情况下,Hibernate才会发出SQL DELETE
语句,为orphanRemoval
提供一个破碎的实现(IMHO)。
简而言之,您需要等待错误被修复,或者编写代码来取消引用并刷新持久性上下文,或者以这种方式使用支持orphanRemoval
的JPA提供程序(EclipseLink 2.3.0)。
在@OneToMany关系中,这与Hibernate JIRA票据hh -6709有关。