I'm trying to understand the cascade
option in Doctrine in Symfony2.
I would like to be able to delete a child entity (and not trigger the foreign key constraint error.)
I have 3 entities:
Report
/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report")
*/
protected $responses;
/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report")
*/
protected $sms;
Response
/**
* @ORM\ManyToOne(targetEntity="Report", inversedBy="responses")
*/
protected $report;
SMS
/**
* @ORM\ManyToOne(targetEntity="Report")
*/
protected $report;
Now I would like to delete a Response
entity but I get
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row:
a foreign key constraint fails (mybundle
.sms
, CONSTRAINT FK_B0A93A77BB333E0D
FOREIGN KEY (reportId
) REFERENCES report
(id
))
Where do I use the cascade
option and which option should I use (detach
or remove
)?
I can do a lot of trial and error to figure this out, but I was hoping for an expert explanation, so I don't overlook something.
Try using
/**
* @ORM\ManyToOne(targetEntity="Report", inversedBy="responses")
* @ORM\JoinColumn(name="reportId", referencedColumnName="id", onDelete="CASCADE")
*/
protected $report;
And then update yor schema. It will add database level Cascading
Ziumin's answer
using the onDelete
option for the ORM JoinColumn
method worked when you want to delete a child item (Owning Side).
But if you want to delete a Response
which is a parent item (Inverse Side), this is when cascade
comes in handy. In the Report
entity I added the following for each of its collections (OneToMany relationships):
Report
/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report", cascade={"remove"})
*/
protected $responses;
/**
* @ORM\OneToMany(targetEntity="SMS", mappedBy="report", cascade={"remove"})
*/
protected $sms;
Now, when I delete a Report
, it removes all of its associated entries in the Response
and SMS
tables.
You may also use cascade=all
for update all actions.
Report
/**
* @ORM\OneToMany(targetEntity="Response", mappedBy="report", cascade={"all"})
*/
protected $responses;
/**
* @ORM\OneToMany(targetEntity="SMS", mappedBy="report", cascade={"all"})
*/
protected $sms;