J'essaie de comprendre l'option cascade
dans Doctrine in Symfony2 .
J'aimerais pouvoir supprimer une entité enfant (sans déclencher l'erreur de contrainte de clé étrangère).
J'ai 3 entités:
Rapport
/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report")
*/
protected $responses;
/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report")
*/
protected $sms;
Réponse
/**
* @ORM\ManyToOne(targetEntity="Report", inversedBy="responses")
*/
protected $report;
SMS
/**
* @ORM\ManyToOne(targetEntity="Report")
*/
protected $report;
Maintenant, je voudrais supprimer une entité Response
mais je reçois
SQLSTATE [23000]: Violation de contrainte d'intégrité: 1451 Impossible de supprimer ou de mettre à jour une ligne parent:
échec d'une contrainte de clé étrangère (mybundle
.sms
, CONSTRAINTFK_B0A93A77BB333E0D
FOREIGN KEY (reportId
) RÉFÉRENCESreport
(id
))
Où dois-je utiliser l'option cascade
et quelle option dois-je utiliser (detach
ou remove
)?
Je peux faire beaucoup d'essais et d'erreurs pour comprendre cela, mais j'espérais une explication par un expert, donc je ne néglige rien.
Essayez d'utiliser
/**
* @ORM\ManyToOne(targetEntity="Report", inversedBy="responses")
* @ORM\JoinColumn(name="reportId", referencedColumnName="id", onDelete="CASCADE")
*/
protected $report;
Et puis mettez à jour votre schéma. Il ajoutera un niveau de base de données en cascade
La réponse de Ziumin
en utilisant l'option
onDelete
pour leORM JoinColumn
cette méthode fonctionnait lorsque vous vouliez supprimer un élément enfant ( côté propriétaire ).
Mais si vous souhaitez supprimer une Response
qui est un élément parent ( côté inverse ), c’est à ce moment-là que cascade
devient pratique. Dans l'entité Report
, j'ai ajouté ce qui suit pour chacune de ses collections (relations OneToMany):
Rapport
/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report", cascade={"remove"})
*/
protected $responses;
/**
* @ORM\OneToMany(targetEntity="SMS", mappedBy="report", cascade={"remove"})
*/
protected $sms;
Maintenant, lorsque je supprime une Report
, elle supprime toutes ses entrées associées dans les tables Response
et SMS
.
Vous pouvez également utiliser cascade=all
pour mettre à jour toutes les actions.
Rapport
/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report", cascade={"all"})
*/
protected $responses;
/**
* @ORM\OneToMany(targetEntity="SMS", mappedBy="report", cascade={"all"})
*/
protected $sms;