如何在多对多关系中使用hibernate和JPA删除孤立实体?

Alu*_*ard 24 java sql hibernate jpa

我想在多对多关系中使用hibernate和JPA删除孤立实体,但我发现的所有属性都是属性.org.hibernate.annotations.CascadeType.DELETE_ORPHAN(即@Cascade(value = {org.hibernate.annotations.CascadeType.DELETE_ORPHAN)),仅适用于一对多关系.

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

HDa*_*ave 10

从"Pro JPA 2"一书中:

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

这是一个无赖,但ManyToMany没有JPA自动孤儿删除.


Pas*_*ent 6

实际上,我使用以下实体进行了测试:

@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>();

    //...
}
Run Code Online (Sandbox Code Playgroud)

并使用以下数据集:

<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>
Run Code Online (Sandbox Code Playgroud)

以下测试方法:

@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();
}
Run Code Online (Sandbox Code Playgroud)

刚过去.低于产生的输出:

Hibernate: select personx0_.id as id17_0_, personx0_.firstName as firstName17_0_, personx0_.lastName as lastName17_0_ from Person personx0_ where personx0_.id=?
Hibernate: select roles0_.persons_id as persons1_1_, roles0_.roles_id as roles2_1_, rolex1_.id as id18_0_, rolex1_.name as name18_0_ from Person_Role roles0_ left outer join Role rolex1_ on roles0_.roles_id=rolex1_.id where roles0_.persons_id=?
Hibernate: delete from Person_Role where persons_id=?
Hibernate: delete from Role where id=?
Hibernate: delete from Role where id=?
Hibernate: delete from Person where id=?
Hibernate: select personx0_.id as id17_, personx0_.firstName as firstName17_, personx0_.lastName as lastName17_ from Person personx0_
Hibernate: select rolex0_.id as id18_, rolex0_.name as name18_ from Role rolex0_

  • 请不要使用这个。即使它不是孤立的,它也会删除相关的实体 (3认同)
  • 是的!我也对此进行了测试。它确实删除了所有依赖的角色(在这种情况下),但是我不能这样做。我只需要删除孤立的...谢谢您的帮助! (2认同)

ich*_*los 6

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