java - onetomany - JPA: eliminación unidireccional de muchos a uno y en cascada
one to one jpa (4)
@Cascade (org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
La anotación dada funcionó para mí.
Por ejemplo :-
public class Parent{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="cct_id")
private Integer cct_id;
@OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER,mappedBy="clinicalCareTeam", orphanRemoval=true)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private List<Child> childs;
}
public class Child{
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="cct_id")
private Parent parent;
}
Digamos que tengo una relación unidireccional @ManyToOne
como la siguiente:
@Entity
public class Parent implements Serializable {
@Id
@GeneratedValue
private long id;
}
@Entity
public class Child implements Serializable {
@Id
@GeneratedValue
private long id;
@ManyToOne
@JoinColumn
private Parent parent;
}
Si tengo un padre P y niños C 1 ... C n haciendo referencia a P, hay una manera limpia y bonita en JPA para eliminar automáticamente los niños C 1 ... C n cuando P se elimina (es decir, entityManager.remove(P)
)?
Lo que estoy buscando es una funcionalidad similar a ON DELETE CASCADE
en SQL.
Crea una relación bidireccional, como esta:
@Entity
public class Parent implements Serializable {
@Id
@GeneratedValue
private long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
private Set<Child> children;
}
Las relaciones en JPA son siempre unidireccionales, a menos que asocies al padre con el niño en ambas direcciones. Las operaciones de REMOVE en cascada del padre al hijo requerirán una relación del padre con el hijo (no solo lo contrario).
Por lo tanto, deberá hacer esto:
- O bien, cambie la relación
@ManyToOne
unidireccional a@ManyToOne
bidireccional, o@OneToMany
unidireccional. A continuación, puedeEntityManager.remove
cascada las operaciones REMOVE para queEntityManager.remove
elimine el elemento principal y los elementosEntityManager.remove
. También puede especificarorphanRemoval
como verdadero, para eliminar los elementos huérfanos cuando la entidad hijo en la colección primaria se establece en nulo, es decir, eliminar el elemento secundario cuando no está presente en la colección de ninguno de los padres. - O bien, especifique la restricción de clave externa en la tabla secundaria como
ON DELETE CASCADE
. Tendrá que invocarEntityManager.clear()
después de llamar a EntityManager.remove ya que el contexto de persistencia necesita ser actualizado: las entidades secundarias no deberían existir en el contexto de persistencia después de que hayan sido eliminadas en la base de datos.
Si está utilizando hibernate como su proveedor de JPA, puede usar la anotación @OnDelete. Esta anotación agregará a la relación el desencadenador ON DELETE CASCADE , que delega la eliminación de los niños a la base de datos.
Ejemplo:
public class Parent {
@Id
private long id;
}
public class Child {
@Id
private long id;
@ManyToOne
@OnDelete(action = OnDeleteAction.CASCADE)
private Parent parent;
}
Con esta solución, una relación unidireccional entre el niño y el padre es suficiente para eliminar automáticamente a todos los niños. Esta solución no necesita ningún oyente, etc. También una consulta como DELETE FROM Parent WHERE id = 1 eliminará los elementos secundarios.