Eigentlich habe ich einen Test mit den folgenden Einheiten:
@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>();
//...
}
Und mit der folgenden Datenmenge:
<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>
Das folgende Testverfahren:
@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();
}
gerade passiert. Unterhalb der Ausgabe erzeugt:
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_
Sie haben den Punkt völlig verpasst (wie Sie es bereits getan haben, als Sie meine Antwort über das optimistische Sperren abgelehnt haben). –
@Pascal Thivent - Sie haben den Punkt verpasst. Dies sollte nicht von der Anwendungsoberfläche aus erfolgen. Dies ist ein Datenbankproblem und sollte von einer korrekt entworfenen Datenbank behandelt werden. Und wenn ich eine Ihrer Antworten abwähle (was ich ehrlich gesagt nicht weiß, wenn ich es tue, schlägt es keine Glocke), dann erwähnt, dass in Ihrem Kommentar, wenn es irrelevant war, mir scheint, dass Sie auf einer Vendetta mehr sind als zu versuchen, das Richtige zu tun. – HLGEM
Mein Kommentar bezieht sich auf das imaginäre "strukturelle Problem", auf das du dich beziehst (du hast den Punkt verpasst, ich bestehe darauf, dass das OP richtige PK/FK hat, du denkst nur nicht auf Objektebene).Dann, ob Sie es glauben oder nicht, ich habe Ihre obige Antwort nicht abgelehnt (zögern Sie nicht, sich mit einem Diamanten-Moderator in Verbindung zu setzen), auch wenn ich denke, dass diese Antwort irrelevant ist (wie der Downvote auf [meine Antwort] (http://stackoverflow.com/) Fragen/2949039/curcency-problem-with-isolation-read-committed/2949534 # 2949534)). Also nein, ich bin nicht auf einer Vendetta (aber Feedback wäre geschätzt worden). –