En realidad, hice una prueba con las siguientes entidades:
@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>();
//...
}
Y con el siguiente conjunto de datos:
<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>
El siguiente método de ensayo:
@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();
}
Sólo pasa. Por debajo de la salida producida:
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_
No entendió el punto (como ya lo hizo cuando rechazó mi respuesta sobre el bloqueo optimista). –
@Pascal Thivent: te perdiste el punto. Esto no es algo que deba hacerse NUNCA desde la interfaz de la aplicación. Este es un problema de base de datos y debe ser manejado por una base de datos correctamente diseñada. Y si abajo voté una de tus respuestas (que honestamente no sé si lo hice, no me suena), mencionar que en tu comentario cuando era irrelevante me parece que estás en una vendetta más que tratar de hacer lo correcto. – HLGEM
Mi comentario es acerca del "problema estructural" imaginario al que también se refiere (no entendió el punto, insisto, el OP tiene PK/FK adecuado, simplemente no está pensando en el nivel del objeto).Entonces, lo creas o no, no rechacé tu respuesta anterior (no dudes en ponerte en contacto con un moderador de diamantes) incluso si creo que esta respuesta es irrelevante (como el voto negativo de [mi respuesta] (http://stackoverflow.com/). preguntas/2949039/concurency-problem-with-isolation-read-committed/2949534 # 2949534)). Así que no, no estoy en una vendetta (pero los comentarios se habrían apreciado). –