15

我对 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”和“AvatarImage”,一个“User”有一个“AvatarImage”,所以“User”和“AvatarImage”之间存在关系。

在“用户”类中,属性如下所示:

// class "User"
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true)
private AvatarImage    avatarImage;

这意味着,如果“avatarImage”属性设置为null,“User”和“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”将删除旧的“avatarImage”,将其设置为“null”,然后保存用户。

但是,我原以为这段代码也应该起作用:

user.setAvatarImage( theNewAvatarImage );
userRepository.save( user );

所以我省略了将“avatarImage”设置为“null”,而只是设置了“theNewAvatarImage”,替换了旧的“avatarImage”。但这不起作用,旧的 AvatarImage 在事务提交时不会从数据库中删除。

有谁知道,为什么第二个代码(只是替换 AvatarImage 而之前没有将其设置为“null”)不起作用?

我非常感谢您提供的任何帮助

非常感谢!

4

2 回答 2

12

This is related to Hibernate JIRA tickets HHH-5559 and HHH-6484. By and large, Hibernate, as of today, requires you to set the reference to null and flush the persistence context, before providing a new value to the relationship (see the test case in HHH-6484); it is only in such a case that Hibernate issues a SQL DELETE statement, providing a broken implementation (IMHO) for orphanRemoval.

In short, you'll need to wait for the bugs to be fixed, or write code to nullify references and flush the persistence context, or use a JPA provider that supports orphanRemoval in this manner (EclipseLink 2.3.0 does).

于 2011-09-22T08:35:22.123 回答
1

在@OneToMany 关系中,这与 Hibernate JIRA ticket HHH-6709有关。请为这些投票,以便引起注意。

于 2013-03-13T15:35:21.183 回答