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

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

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

从“Pro JPA 2”一书中:

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

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

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

@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 roles = new HashSet(); //... } @Entity public class Role { @Id @GeneratedValue private Long id; private String name; @ManyToMany(mappedBy = "roles") private Set persons = new HashSet(); //... } 

并使用以下数据集:

                

以下测试方法:

 @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 findAllPersons() { return entityManager.createQuery("from Person").getResultList(); } private List findAllRoles() { return entityManager.createQuery("from Role").getResultList(); } 

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

 Hibernate:选择personx0_.id作为id17_0_,personx0_.firstName作为firstName17_0_,personx0_.lastName作为lastName17_0_来自Person personx0_ where personx0_.id =?
 Hibernate:选择roles0_.persons_id为persons1_1_,roles0_.roles_id为roles2_1_,rolex1_.id为id18_0_,rolex1_.name为name18_0_来自Person_Role roles0_左外连接角色rolex1_ on roles0_.roles_id = rolex1_.id其中roles0_.persons_id =?
 Hibernate:从Person_Role中删除persons_id =?
 Hibernate:从Role中删除id =?
 Hibernate:从Role中删除id =?
 Hibernate:从人物中删除id =?
 Hibernate:选择personx0_.id为id17_,personx0_.firstName为firstName17_,personx0_.lastName为lastName17_ from person personx0_
 Hibernate:从rolex0_角色中选择rolex0_.id为id18_,rolex0_.name为name18_

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

不要使用hibernate,编写SQl代码并以基于集合的方式直接在数据库上运行它。 然后修复数据库结构问题,允许您首先获取孤立记录。 如果你甚至有孤立的记录,这是一个设计很差的数据库的标志。 这个shouod是一次性修复,而不是从应用程序代码运行的东西。 很遗憾你没有建立适当的PK / FK关系。

尝试这个:

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