Как удалить несвязанные объекты, используя hibernate и JPA, в отношениях «многие ко многим»? - PullRequest
22 голосов
/ 16 июня 2010

Я хочу удалить осиротевшие сущности, используя hibernate и JPA для отношения «многие ко многим», но все, что я нашел, это этот атрибут атрибут. org.hibernate.annotations.CascadeType.DELETE_ORPHAN (т.е. @Cascade (value = {org.hibernate.annotations.CascadeType.DELETE_ORPHAN)), который работает только для отношений один-ко-многим.

Я хочу знать, смогу ли я удалить сирот в моих отношениях «многие ко многим».

Ответы [ 4 ]

10 голосов
/ 05 января 2013

Из книги «Pro JPA 2»:

Только связи с одним количеством элементов на стороне источника могут разрешить удаление сирот, поэтому опция orphanRemoval определена в @OneToOne и @OneToManyаннотации отношений, но ни в аннотациях @ManyToOne, ни в @ManyToMany.

Это облом, но для ManyToMany нет автоматического удаления осиротевших JPA.

6 голосов
/ 17 июня 2010

На самом деле я провел тест со следующими объектами:

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

Просто проходит.Ниже произведенной продукции:

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_
2 голосов
/ 15 октября 2012

Пока что для аннотации ManyToMany отсутствует атрибут orphanRemoval . У меня такая же проблема. И предложение включить его в базу данных не является решением проблемы. Вся философия JPA заключается в против реализации логики в базе данных, но через сопоставления.

0 голосов
/ 19 сентября 2012

попробуйте это:

@ManyToMany(cascade = CascadeType.ALL, orphanRemoval=true, fetch = FetchType.LAZY, mappedBy = "yourObject")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...