JPA 2.0 / Hibernate和“orphanRemoval”:只是替换一个实体不会删除旧实体 [英] JPA 2.0 / Hibernate and "orphanRemoval": Just replacing an entity does not remove the old one

查看:126
本文介绍了JPA 2.0 / Hibernate和“orphanRemoval”:只是替换一个实体不会删除旧实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



首先我的设置:


  • Spring 3.0.5.RELEASE

  • SprnigData JPA 1.0.1.RELEASE

  • Hibernate 3.5.2-Final
  • li>
  • DBMS:PostgreSQL 9.0我有两个相当简单的实体类,User和AvatarImage ,一个用户有一个AvatarImage,所以介于用户和AvatarImage之间存在关系。



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

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

    这意味着,如果avatarImage属性设置为null,则用户和AvatarImage被移除,orphanRemoval机制将从数据库中删除avatarImage(如果我错了,请纠正我)。

    为某个用户提供的avatarImage,我现在必须写下:

      user.setAvatarImage(null); //首先将其设置为空
    userRepository.save(user); //现在orphanRemoval将删除旧的

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

    因此,首先将avatarImage属性设置为null,保存user,然后设置新的AvatarImagetheNewAvatarImage,再次保存用户。



    这是目前唯一适用于我的方式 - orphanRemoval会在设置时删除旧的avatarImage它会空,然后保存用户。

    但是,我一直认为这段代码也应该可以工作:

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

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



    有谁知道,为什么第二个代码(只是替换AvatarImage而没有设置它到空之前)不起作用?



    我真的很感谢你可以提供任何帮助



    谢谢很多!

    解决方案

    这与Hibernate JIRA票据有关 HHH-5559 HHH-6484 。总的来说,到目前为止,Hibernate要求您在为关系提供新值之前将引用设置为null并刷新持久化上下文(请参阅HHH-6484中的测试用例)。只有在这种情况下,Hibernate发出SQL DELETE 语句,为 orphanRemoval 提供了一个破坏的实现(恕我直言) 。

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


    I have question regarding JPA 2.0, Hibernate and "orphanRemoval".

    First my setup:

    • Spring 3.0.5.RELEASE
    • SprnigData JPA 1.0.1.RELEASE
    • Hibernate 3.5.2-Final
    • DBMS: PostgreSQL 9.0

    I have two rather simple entity classes, "User" and "AvatarImage", A "User" has an "AvatarImage", and so between "User" and "AvatarImage" there is the relationship.

    In the class "User", the property looks like this:

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

    So that means, if the "avatarImage" property gets set to null, the reference between "User" and "AvatarImage" is removed and "orphanRemoval" mechanism will delete the "avatarImage" from the database (please correct me if I'm wrong).

    So when I update the "avatarImage" for a certain user, I currently have to write this:

    user.setAvatarImage( null );  // First set it to null
    userRepository.save( user );  // Now "orphanRemoval" will delete the old one
    
    user.setAvatarImage( theNewAvatarImage );
    userRepository.save( user );
    

    So setting the "avatarImage" property first to null, saving the "user", and then set the new AvatarImage "theNewAvatarImage", again saving the user.

    This is the only way it currently works for me - the "orphanRemoval" will delete the old "avatarImage" on setting it to "null" and then saving the user.

    But, I would have thought that this code should also work:

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

    So I omit setting the "avatarImage" to "null" but just setting "theNewAvatarImage", replacing the old "avatarImage". But this does not work, the old AvatarImage does not get removed from the database upon transaction commit.

    Does anyone know, why the second code (just replacing the AvatarImage without setting it to "null" before) does not work?

    I really appreciate any help you can offer

    Thanks a lot!

    解决方案

    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).

    这篇关于JPA 2.0 / Hibernate和“orphanRemoval”:只是替换一个实体不会删除旧实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆