【问题标题】:How do I delete orphan entities using hibernate and JPA on a many-to-many relationship?如何在多对多关系上使用休眠和 JPA 删除孤立实体?
【发布时间】:2011-03-04 13:56:24
【问题描述】:

我想在多对多关系上使用休眠和 JPA 删除孤立实体,但我发现的只是这个属性。 org.hibernate.annotations.CascadeType.DELETE_ORPHAN(即@Cascade(value={org.hibernate.annotations.CascadeType.DELETE_ORPHAN)),仅适用于一对多关系。

我想知道我是否可以删除我的多对多关系中的孤儿。

【问题讨论】:

    标签: java sql hibernate jpa


    【解决方案1】:

    来自“Pro JPA 2”一书:

    只有在源端具有单一基数的关系才能 启用孤立删除,这就是 orphanRemoval 选项的原因 在 @OneToOne 和 @OneToMany 关系注释上定义,但是 在 @ManyToOne 或 @ManyToMany 注释上都没有。

    这很糟糕,但没有针对 ManyToMany 的 JPA 自动孤儿删除。

    【讨论】:

      【解决方案2】:

      其实我用以下实体做了一个测试:

      @Entity
      public class Person {
          @Id
          @GeneratedValue
          private Long id;
          private String firstName;
          private String lastName;
      
          @ManyToMany
          @Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
          private Set<Role> roles = new HashSet<Role>();
      
          //...
      }
      
      @Entity
      public class Role {
          @Id
          @GeneratedValue
          private Long id;
      
          private String name;
      
          @ManyToMany(mappedBy = "roles")
          private Set<Person> persons = new HashSet<Person>();
      
          //...
      }
      

      并使用以下数据集:

      <dataset>
          <PERSON id="1" firstname="john" lastname="doe"/>
          <PERSON id="2" firstname="clark" lastname="kent"/>
          <PERSON id="3" firstname="james" lastname="bond"/>
          <ROLE id="1" name="foo"/>
          <ROLE id="2" name="bar"/>
          <ROLE id="3" name="boo"/>
          <ROLE id="4" name="baz"/>
          <PERSON_ROLE persons_id="1" roles_id="1"/>
          <PERSON_ROLE persons_id="1" roles_id="2"/>
          <PERSON_ROLE persons_id="2" roles_id="2"/>
          <PERSON_ROLE persons_id="2" roles_id="3"/>
          <PERSON_ROLE persons_id="3" roles_id="1"/>
          <PERSON_ROLE persons_id="3" roles_id="4"/>
      </dataset>
      

      以下测试方法:

      @Test
      public void testCascadeDeleteOrphanOnDelete() {
          Person person = entityManager.find(Person.class, 1L);
          entityManager.remove(person);
          ReflectionAssert.assertPropertyLenientEquals("id", Arrays.asList(2, 3), findAllPersons());
          ReflectionAssert.assertPropertyLenientEquals("id", Arrays.asList(3, 4), findAllRoles());
      
      }
      
      private List<Person> findAllPersons() {
          return entityManager.createQuery("from Person").getResultList();
      }
      
      private List<Role> findAllRoles() {
          return entityManager.createQuery("from Role").getResultList();
      }
      

      刚刚过去。在生成的输出下方:

      休眠:从 Person personx0_ where personx0_.id=? 休眠:选择roles0_.persons_id 作为persons1_1_,roles0_.roles_id 作为roles2_1_,rolex1_.id 作为id18_0_,rolex1_.name 作为name18_0_ 从Person_Role 角色0_ 左外连接角色rolex1_ onroles0_.roles_id=rolex1_.id whereroles0_.persons_id=? 休眠:从 Person_Role 中删除 person_id=? 休眠:从角色中删除 id=? 休眠:从角色中删除 id=? 休眠:从 id=? 的 Person 中删除 休眠:从 Person personx0_ 中选择 personx0_.id 作为 id17_,personx0_.firstName 作为 firstName17_,personx0_.lastName 作为 lastName17_ 休眠:从角色rolex0_中选择rolex0_.id作为id18_,rolex0_.name作为name18_

      【讨论】:

      • 是的!我也测试过这个。它确实删除了所有依赖角色(在这种情况下),但我不能这样做。我只需要删除孤儿...谢谢您的帮助!
      • @user368453:确实,这就像 Hibernate 级联 DELETE(我现在明白这不是你想要的)。我想知道 Hibernate 是否可以做得更好。
      • 是的!我希望它可以......但似乎我必须在数据库上创建一个触发器才能做到这一点=/
      • 这个解决方案也依赖于 Hibernate 并且破坏了 JPA 的可移植性。
      • 请不要使用这个。即使它不是孤立的,它也会删除相关实体
      【解决方案3】:

      到目前为止,ManyToMany 注释还没有 orphanRemoval 属性。我也有同样的问题。并且在数据库上实施它的建议并不能解决问题。 JPA 的整个理念是反对在数据库上实现逻辑,但通过映射。

      【讨论】:

        【解决方案4】:

        试试这个:

        @ManyToMany(cascade = CascadeType.ALL, orphanRemoval=true, fetch = FetchType.LAZY, mappedBy = "yourObject")
        

        【讨论】:

        • 就像下面的评论说,ManyToMany-annotation 上没有这样的属性。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 2023-03-05
        • 1970-01-01
        • 2017-09-21
        • 2018-05-14
        • 2011-09-17
        相关资源
        最近更新 更多