Estoy un poco confundido sobre el orphanRemoval
atributo JPA 2.0 .
Creo que puedo ver que es necesario cuando uso las herramientas de generación de DB de mi proveedor de JPA para crear la base de datos subyacente DDL para tener una ON DELETE CASCADE
relación particular.
Sin embargo, si el DB existe y ya tiene una ON DELETE CASCADE
relación, ¿no es esto suficiente para poner en cascada la eliminación de manera adecuada? ¿Qué hace el orphanRemoval
además?
Salud
fuente
Un ejemplo tomado aquí :
Cuando
Employee
se elimina un objeto de entidad, la operación de eliminación se conecta en cascada alAddress
objeto de entidad al que se hace referencia . En este sentido,orphanRemoval=true
ycascade=CascadeType.REMOVE
son idénticos, y siorphanRemoval=true
se especifica,CascadeType.REMOVE
es redundante.La diferencia entre las dos configuraciones está en la respuesta a la desconexión de una relación. Por ejemplo, como cuando se configura el campo de dirección
null
a otroAddress
objeto.Si
orphanRemoval=true
se especifica, laAddress
instancia desconectada se elimina automáticamente. Esto es útil para limpiar objetos dependientes (por ejemploAddress
) que no deberían existir sin una referencia de un objeto propietario (por ejemploEmployee
).Si solo
cascade=CascadeType.REMOVE
se especifica, no se realiza ninguna acción automática ya que desconectar una relación no es una operación de eliminación.Para evitar referencias colgantes como resultado de la eliminación de huérfanos, esta función solo debe habilitarse para los campos que contienen objetos dependientes privados no compartidos.
Espero que esto lo aclare más.
fuente
En el momento en que elimine una entidad secundaria de la colección, también eliminará esa entidad secundaria de la base de datos. orphanRemoval también implica que no puede cambiar de padres; Si hay un departamento que tiene empleados, una vez que elimine a ese empleado para colocarlo en otro departamento, habrá eliminado sin darse cuenta a ese empleado de la base de datos en flush / commit (lo que ocurra primero). La moral es establecer huérfanoRemoval en verdadero siempre que esté seguro de que los hijos de ese padre no migrarán a un padre diferente a lo largo de su existencia. Al activar huérfano, Removal también agrega automáticamente REMOVE a la lista en cascada.
fuente
department.remove(emp);
ese empleado se elimina de la tabla emp sin ni siquiera llamarcommit()
El mapeo JPA equivalente para el DDL
ON DELETE CASCADE
escascade=CascadeType.REMOVE
. La eliminación huérfana significa que las entidades dependientes se eliminan cuando se destruye la relación con su entidad "principal". Por ejemplo, si un hijo se elimina de una@OneToMany
relación sin eliminarlo explícitamente en el administrador de la entidad.fuente
cascade=CascadeType.REMOVE
NO es equivalente aON DELETE CASCADE
. Al eliminar en el código de la aplicación y no afecta a DDL, otro ejecutado en DB. Ver stackoverflow.com/a/19696859/548473La diferencia es:
- orphanRemoval = true: la entidad "Secundaria" se elimina cuando ya no se hace referencia a ella (su padre no se puede eliminar).
- CascadeType.REMOVE: la entidad "Secundaria" se elimina solo cuando se elimina su "Principal".
fuente
Transiciones de estado de entidad
JPA traduce las transiciones de estado de la entidad a sentencias SQL, como INSERT, UPDATE o DELETE.
Cuando usted es
persist
una entidad, está programando la instrucción INSERT para que se ejecute cuandoEntityManager
se vacía, de forma automática o manual.cuando eres
remove
una entidad, estás programando la declaración DELETE, que se ejecutará cuando se vacíe el Contexto de persistencia.Transiciones de estado de entidad en cascada
Por conveniencia, JPA le permite propagar las transiciones de estado de la entidad de las entidades principales a las secundarias.
Entonces, si tiene una
Post
entidad principal que tiene una@OneToMany
asociación con laPostComment
entidad secundaria:La
comments
colección en laPost
entidad se asigna de la siguiente manera:CascadeType.ALL
El
cascade
atributo le dice al proveedor de JPA que pase la transición del estado de laPost
entidad de la entidad principal a todas lasPostComment
entidades contenidas en elcomments
colección.Entonces, si elimina la
Post
entidad:El proveedor de JPA eliminará
PostComment
primero la entidad, y cuando se eliminen todas las entidades secundarias, también eliminará laPost
entidad:Retiro de huérfanos
Cuando establezca el
orphanRemoval
atributo entrue
, el proveedor de JPA programará unaremove
operación cuando la entidad secundaria se elimine de la colección.Entonces, en nuestro caso,
El proveedor de JPA eliminará el
post_comment
registro asociado ya que laPostComment
entidad ya no está referenciada en lacomments
colección:EN ELIMINAR CASCADA
El
ON DELETE CASCADE
se define en el nivel FK:Una vez que haga eso, si elimina una
post
fila:El
post_comment
motor de la base de datos elimina automáticamente todas las entidades asociadas . Sin embargo, esta puede ser una operación muy peligrosa si elimina una entidad raíz por error.Conclusión
La ventaja de JPA
cascade
y lasorphanRemoval
opciones es que también puede beneficiarse del bloqueo optimista para evitar actualizaciones perdidas .Si usa el mecanismo de cascada JPA, no necesita usar el nivel DDL
ON DELETE CASCADE
, que puede ser una operación muy peligrosa si elimina una entidad raíz que tiene muchas entidades secundarias en varios niveles.Para obtener más detalles sobre este tema, consulte este artículo .
fuente
CascadeType
. Es un mecanismo complementario. Ahora, está confundiendo la eliminación con la persistencia. La eliminación de huérfanos se trata de eliminar asociaciones sin referencia, mientras que la persistencia se trata de salvar nuevas entidades. Debe seguir los enlaces proporcionados en la respuesta para comprender mejor estos conceptos.@GaryK respuesta es absolutamente genial, he pasado una hora buscando una explicación
orphanRemoval = true
frenteCascadeType.REMOVE
y me ayudó a entender.En resumen:
orphanRemoval = true
funciona de la misma manera queCascadeType.REMOVE
SÓLO SI eliminamos object (entityManager.delete(object)
) y queremos que también se eliminen los objetos del niño.En una situación completamente diferente, cuando busquemos algunos datos como
List<Child> childs = object.getChilds()
y luego eliminemos un child (entityManager.remove(childs.get(0)
) usandoorphanRemoval=true
, la entidad correspondientechilds.get(0)
se eliminará de la base de datos.fuente
la eliminación huérfana tiene el mismo efecto que EN ELIMINAR CASCADA en el siguiente escenario: - Digamos que tenemos una relación simple de uno a uno entre la entidad estudiantil y una entidad guía, donde muchos estudiantes pueden asignarse a la misma guía y en la base de datos tenemos un relación de clave externa entre el alumno y la tabla de guía de modo que la tabla del alumno tenga id_guide como FK.
// La entidad principal
En este escenario, la relación es tal que la entidad estudiantil es la propietaria de la relación y, como tal, necesitamos guardar la entidad estudiantil para poder conservar todo el gráfico del objeto, por ejemplo
Aquí estamos mapeando la misma guía con dos objetos de estudiantes diferentes y dado que se utiliza CASCADE.PERSIST, el gráfico de objetos se guardará como se muestra a continuación en la tabla de la base de datos (MySql en mi caso)
Mesa ESTUDIANTE: -
ID Nombre Dept Id_Guide
1 Roy ECE 1
2 Nick ECE 1
Tabla de GUÍA: -
ID NOMBRE Salario
1 Juan $ 1500
y ahora si quiero eliminar a uno de los estudiantes, usando
y cuando se elimina un registro de estudiante, el registro de guía correspondiente también debe eliminarse, ahí es donde entra en escena el atributo CASCADE.REMOVE en la entidad de Estudiante y lo que hace es; elimina al estudiante con el identificador 1 y el objeto de guía correspondiente (identificador 1) Pero en este ejemplo, hay un objeto de estudiante más que se asigna al mismo registro de guía y, a menos que usemos el atributo orphanRemoval = true en la entidad de guía, el código de eliminación anterior no funcionará.
fuente