JPA 2.0 / 休眠和“orphanRemoval”:只是替换一个实体并不能删除旧的实体

2022-09-03 15:09:18

我有关于JPA 2.0,Hibernate和“orphanRemoval”的问题。

首先我的设置:

  • 春季 3.0.5.发布
  • SprnigData JPA 1.0.1.RELEASE
  • 休眠 3.5.2-决赛
  • DBMS: PostgreSQL 9.0

我有两个相当简单的实体类,“User”和“AvatarImage”,一个“User”有一个“AvatarImage”,所以在“User”和“AvatarImage”之间有关系。

在类“User”中,该属性如下所示:

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

这意味着,如果“avatarImage”属性设置为null,则“User”和“AvatarImage”之间的引用将被删除,“orphanRemoveval”机制将从数据库中删除“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”,再次保存用户。

这是它目前为我工作的唯一方式 - “orphanRemoval”将删除旧的“avatarImage”,将其设置为“null”,然后保存用户。

但是,我本来以为这段代码也应该工作:

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

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

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

我真的很感激你能提供的任何帮助

多谢!


答案 1

这与Hibernate JIRA门票HHH-5559HHH-6484有关。总的来说,Hibernate,从今天开始,要求您在为关系提供新值之前将引用设置为null并刷新持久性上下文(请参阅HHH-6484中的测试用例);只有在这样的情况下,Hibernate才会发出SQL语句,为.DELETEorphanRemoval

简而言之,您需要等待错误修复,或者编写代码来使引用无效并刷新持久性上下文,或者使用以这种方式支持的JPA提供程序(EclipseLink 2.3.0确实如此)。orphanRemoval


答案 2

截至@OneToMany关系,这与Hibernate JIRA票证HHH-6709有关。请投票支持这些,以便引起一些关注。


推荐