我对JPA 2.0,Hibernate和“orphanRemoval”有疑问。

首先我的设置:

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

  • 我有两个相当简单的实体类,“用户”和“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-5559HHH-6484有关。总的来说,从今天开始,Hibernate要求您将引用设置为null并刷新持久性上下文,然后再为该关系提供新的值(请参见HHH-6484中的测试用例);只有在这种情况下,Hibernate才会发出SQL DELETE语句,从而为orphanRemoval提供损坏的实现(IMHO)。

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

    07-24 13:36