J'ai essayé de rassembler quelques informations sur les méthodes suivantes pour supprimer automatiquement l'entité enfant lorsqu'une entité parente est supprimée. Il semble que la méthode la plus courante consiste à utiliser l'une de ces trois annotations: cascade = {"remove"} OR orphanRemoval = true OR ondelete = "CASCADE" .
Je suis un peu confus au sujet du troisième: ondelete = "CASCADE" , car les explications dans la doctrine, la documentation officielle sur celui-ci est très rare) et j'aimerais que quelqu'un puisse me confirmer les informations suivantes que j'ai recueillies et comprises de mes recherches sur le net et expérience ...
CE QU'IL FAIT
cascade = {"remove"}
==> l'entité du côté inverse est supprimée lorsque l'entité du côté propriétaire l'est. Même si vous êtes dans une multitude avec une autre entité propriétaire.
- doit être utilisé sur la collection (donc dans la relation OneToMany ou ManyToMany)
- implémentation dans l'ORM
orphanRemoval = true
==> l'entité du côté inverse est supprimée lorsque l'entité du côté propriétaire est ET elle n'est plus connectée à aucune autre entité côté propriétaire. (réf. doctrine official_doc
- implémentation dans l'ORM
- peut être utilisé avec OneToOne, OnetoMany ou ManyToMany
onDelete = "CASCADE"
==> cela ajoutera On Delete Cascade à la colonne de clé étrangère dans la base de données
- Cette stratégie est un peu difficile à faire mais peut être très puissante et rapide. (réf. doctrine official_doc ... mais je n'ai pas lu plus d'explications)
- ORM doit faire moins de travail (par rapport aux deux méthodes précédentes) et devrait donc avoir de meilleures performances.
autres informations
- toutes ces 3 façons de faire sont implémentées sur des entités de relation bidirectionnelles (à droite ??? )
- en utilisant cascade = {"remove"} contourne complètement toute clé étrangère onDelete = CASCADE. (réf. doctrine_official_doc )
EXEMPLE D'UTILISATION DANS CODE
- orphanRemoval et cascade = {"remove"} sont définis dans la classe d'entité inversée.
- ondelete = "CASCADE" est défini dans l'entité propriétaire
- vous pouvez aussi simplement écrire @ORM \ JoinColumn (onDelete = "CASCADE") et laisser la doctrine gérer les noms de colonnes
cascade = {"supprimer"}
/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", cascade={"remove"})
*/
protected $Phonenumbers
orphanRemoval = true
/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", orphanRemoval=true)
*/
protected $Phonenumbers
onDelete = "CASCADE"
/**
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/
protected $contact;
Réponses:
onDelete="CASCADE"
est géré par la base de données elle-même.cascade={"remove"}
est géré par la doctrine.onDelete="CASCADE"
est plus rapide car les opérations sont effectuées au niveau de la base de données plutôt que par doctrine. La suppression est effectuée par le serveur de base de données et non par Doctrine. Aveccascade={"remove"}
doctrine doit gérer l'entité elle-même et effectuera des vérifications supplémentaires pour voir si elle n'a pas d'autres entités propriétaires. Lorsqu'aucun autre n'existe, il supprimera l'entité. Mais cela crée des frais généraux.cascade = {"supprimer"}
orphanRemoval = "vrai"
onDelete = "CASCADE"
la source