Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在多对多关系中使用hibernate和JPA删除孤立实体?_Java_Sql_Hibernate_Jpa - Fatal编程技术网

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

Java 如何在多对多关系中使用hibernate和JPA删除孤立实体?,java,sql,hibernate,jpa,Java,Sql,Hibernate,Jpa,我想在多对多关系中使用hibernate和JPA删除孤立实体,但我只找到了这个属性。org.hibernate.annotations.CascadeType.DELETE_ORPHAN(即@Cascade(value={org.hibernate.annotations.CascadeType.DELETE_ORPHAN)),它仅适用于一对多关系 我想知道是否可以删除多对多关系中的孤立项。实际上,我对以下实体进行了测试: @Entity public class Person { @I

我想在多对多关系中使用hibernate和JPA删除孤立实体,但我只找到了这个属性。org.hibernate.annotations.CascadeType.DELETE_ORPHAN(即@Cascade(value={org.hibernate.annotations.CascadeType.DELETE_ORPHAN)),它仅适用于一对多关系


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

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

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

    //...
}
@实体
公共阶层人士{
@身份证
@生成值
私人长id;
私有字符串名;
私有字符串lastName;
@许多
@级联(value=org.hibernate.annotations.CascadeType.DELETE\u孤儿)
私有集角色=新HashSet();
//...
}
@实体
公共阶级角色{
@身份证
@生成值
私人长id;
私有字符串名称;
@许多(mappedBy=“角色”)
private Set persons=new HashSet();
//...
}
并使用以下数据集:

<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();
}
@测试
public void testcascadeDeleteOrphannedOnDelete(){
Person-Person=entityManager.find(Person.class,1L);
实体经理(人);
ReflectionAssert.AssertPropertyLeneIntequals(“id”,Arrays.asList(2,3),findAllPersons());
ReflectionAssert.AssertPropertyLineeQuals(“id”,Arrays.asList(3,4),findAllRoles());
}
私有列表findAllPersons(){
返回entityManager.createQuery(“来自个人”).getResultList();
}
私有列表findAllRoles(){
返回entityManager.createQuery(“来自角色”).getResultList();
}
仅通过。在生成的输出下面:

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_ 休眠:从Person personx0中选择personx0\u0.id作为id17\u0,personx0\u0.firstName作为firstName17\u0,personx0\u0.lastName作为lastName17\u0? 休眠:选择角色0。角色id为角色1,角色0。角色id为角色2,角色1。id为id18,角色1。名称为名称18。角色角色0。左外部联接角色角色1。角色0。角色id=角色1。id,其中角色0。角色id=? 休眠:从Person_角色中删除,其中Person_id=? 休眠:从id=? 休眠:从id=? Hibernate:从id=? 休眠:从Person personx0中选择personx0\u0.id作为id17\u0,personx0\u0.firstName作为firstName17\u0,personx0\u0.lastName作为lastName17\u0_ 休眠:从角色rolex0中选择rolex0\u0.id作为id18\u0,rolex0\u0.name作为name18\u0_ 试试这个:

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

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

摘自《Pro JPA 2》一书:

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


这很糟糕,但是很多人都没有JPA自动删除孤立角色。

是的!我也测试过。它确实删除了所有依赖角色(在本例中),但我不能这样做。我只需要删除孤立角色……谢谢你的帮助!@user368453:事实上,这就像Hibernate级联删除一样(我现在明白这不是你想要的)。我想知道Hibernate是否可以做得更好。是的!我希望它可以…但似乎我必须在数据库上创建一个触发器来实现这一点=/此解决方案还依赖于Hibernate并破坏JPA的可移植性。请不要使用此方法。它会删除相关实体,即使它不是孤立的,就像下面的注释所说的,ManyToMany-a上没有这样的属性注释。