web-dev-qa-db-fra.com

Comment utiliser l'option en cascade dans Symfony2 Doctrine?

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, CONSTRAINT FK_B0A93A77BB333E0D FOREIGN KEY (reportId) RÉFÉRENCES report (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.

15
user1383418

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

27
Ziumin

La réponse de Ziumin

en utilisant l'option onDelete pour le ORM 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.

11
user1383418

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;
1
virtustilus