cascade = {“eliminar”} VS orphanRemoval = true VS ondelete = "CASCADE

93

Traté de recopilar poca información sobre las siguientes formas de eliminar automáticamente la entidad secundaria cuando se elimina una entidad principal. Parece que la forma más común es utilizar una de esas tres anotaciones: cascade = {"remove"} O orphanRemoval = true O ondelete = "CASCADE" .

estoy un poco confundido sobre el tercero: ondelete = "CASCADE" , ya que la explicación en la documentación oficial de la doctrina sobre este es muy escasa) y me encantaría que alguien pudiera confirmarme la siguiente información que recopilé y entiendo de mi investigación sobre el red y experiencia ...

QUE HACE

cascade = {"remove"}
==> la entidad en el lado inverso se elimina cuando la entidad del lado propietario es. Incluso si está en muchos casos con otra entidad del lado propietario.
- debe usarse en la colección (es decir, en la relación OneToMany o ManyToMany)
- implementación en el ORM

orphanRemoval = true
==> la entidad en el lado inverso se elimina cuando la entidad del lado propietario es Y ya no está conectada a ninguna otra entidad del lado propietario. (ref. doctrine official_doc - implementación en el ORM
- se puede usar con OneToOne, OnetoMany o ManyToMany

onDelete = "CASCADE"
==> esto agregará On Delete Cascade a la columna de clave externa en la base de datos
. Esta estrategia es un poco complicada de hacer bien, pero puede ser muy poderosa y rápida. (ref. doctrine official_doc ... pero no he leído más explicaciones)
- ORM tiene que hacer menos trabajo (en comparación con las dos formas anteriores de hacerlo) y por lo tanto debería tener un mejor rendimiento.

otra información
- todas esas 3 formas de hacerlo se implementan en entidades de relación bidireccional ( ¿verdad ??? )
- usando cascade = {"remove"} omite por completo cualquier clave externa onDelete = CASCADE. (ref. doctrine_official_doc )

EJEMPLO DE CÓMO USARLO EN CÓDIGO

  • orphanRemoval y cascade = {"remove"} se definen en la clase de entidad inversa.
  • ondelete = "CASCADE" está definido en la entidad propietaria
  • también puede escribir @ORM \ JoinColumn (onDelete = "CASCADE") y dejar que doctrine maneje los nombres de las columnas

cascade = {"eliminar"}

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", cascade={"remove"})
*/
protected $Phonenumbers

orphanRemoval = verdadero

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", orphanRemoval=true)
*/
protected $Phonenumbers

onDelete = "CASCADA"

/** 
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/ 
protected $contact; 
Alexis_D
fuente
1
tiene una buena explicación stackoverflow.com/questions/25515007/…
Gregsparrow

Respuestas:

61

onDelete="CASCADE"es administrado por la propia base de datos. cascade={"remove"}es administrado por doctrina.

onDelete="CASCADE"es más rápido porque las operaciones se realizan a nivel de base de datos en lugar de por doctrina. La eliminación la realiza el servidor de la base de datos y no Doctrine. Con la cascade={"remove"}doctrina tiene que gestionar la propia entidad y realizará comprobaciones adicionales para ver si no tiene otras entidades propietarias. Cuando no exista otro, eliminará la entidad. Pero esto crea gastos generales.


cascade = {"eliminar"}

  • la entidad del lado inverso se elimina cuando la entidad del lado propietario es. Incluso si está en muchos casos con otra entidad del lado propietario. No, si la entidad es propiedad de otra persona. No se borrará.
  • debe usarse en la colección (por lo tanto, en la relación OneToMany o ManyToMany)
  • implementación en el ORM

orphanRemoval = "verdadero"

  • la entidad en el lado inverso se elimina cuando la entidad del lado propietario es Y ya no está conectada a ninguna otra entidad del lado propietario. No exactamente, esto hace que la doctrina se comporte como si no fuera propiedad de otra entidad y, por lo tanto, la elimine.
  • implementación en el ORM
  • se puede utilizar con OneToOne, OnetoMany o ManyToMany

onDelete = "CASCADA"

  • esto agregará On Delete Cascade a la columna de clave externa EN LA BASE DE DATOS
  • Esta estrategia es un poco complicada de hacer bien, pero puede ser muy poderosa y rápida. (esta es una cita del tutorial oficial de doctrina ... pero no he visto mucha más explicación)
  • ORM tiene que hacer menos trabajo (en comparación con las dos formas anteriores de hacerlo) y, por lo tanto, debería tener un mejor rendimiento.
Waaghals
fuente
3
@ waaghals. Acerca de sus comentarios sobre la cascada = {"eliminar"} ==> Tengo una relación ManyToMany entre el artículo de la entidad y la categoría. Cuando elimino un artículo ($ em-> remove ($ artículo);) elimina todas las categorías vinculadas a este artículo, INCLUSO si esas categorías también están vinculadas a otros artículos. entonces yo diría que no se comporta como escribes.
Alexis_D
2
@ waaghals. Acerca de sus comentarios sobre orphanRemoval = "true" La oración que escribí "la entidad en el lado inverso se elimina cuando la entidad del lado propietario lo es, y no es propiedad de ninguna otra entidad" se cita de las páginas oficiales de doctrine. doctrina = remoción de huérfanos .
Alexis_D
1
@Alexis_D, totalmente de acuerdo con sus comentarios La respuesta es incorrecta y puede ser realmente confusa para los novatos
Stepan Yudin
3
Uno de los ejemplos más claros que he leído: gist.github.com/pylebecq/f844d1f6860241d8b025
Victor S
El enlace de @VictorS es muy claro. Ya no estoy trabajando con Doctrine, así que siento que no puedo actualizar mi respuesta sin saber de primera mano cómo funciona. Si alguien pudiera actualizar mi respuesta, sería genial.
Waaghals