orm: Order of referenced child deletions not correct when referencing to itself
Bug Report
Q | A |
---|---|
BC Break | no |
Version | 2.14.0 |
Summary
The order in which the UoW wants to delete children is somehow missing a dependency when there is an association to the same class even if you specified cascade: ['remove']
.
Given you have
- Parent -> has an association to children with
cascade: ['remove']
- Child 1
- Child 2 -> has an association to Child 1 with
cascade: ['remove']
.
Now you delete the parent. Doctrine tries to remove Child 1 first instead of Child 2 causing a foreign constraint violation:
Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (
test
.child_entities
, CONSTRAINTFK_DAEB194156A273CC
FOREIGN KEY (origin_id
) REFERENCESchild_entities
(id
))
How to reproduce
I’ve created a test setup because I’m not familiar with the internals of ORM at all. So here we go:
- Clone https://github.com/Toflar/doctrine-orm-bug-reproducer
- Run
composer install
- Adjust dummy mysql connection example in
bootstrap.php
. - Run
bin/doctrine orm:schema-tool:drop --force && bin/doctrine orm:schema-tool:create
- Run
php test.php
.
Expected behavior
It should not throw an exception. Doctrine should remove Child 2 first.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 15 (12 by maintainers)
Commits related to this issue
- Include a functional test for issue #10348 Co-authored-by: Matthias Pigulla <mp@webfactory.de> — committed to mpdude/doctrine2 by simonberger a year ago
- Include a functional test for issue #10348 Co-authored-by: Matthias Pigulla <mp@webfactory.de> — committed to mpdude/doctrine2 by simonberger a year ago
- Include a functional test for issue #10348 Co-authored-by: Matthias Pigulla <mp@webfactory.de> — committed to mpdude/doctrine2 by simonberger a year ago
- Add a test case to show #10348 has been fixed by #10566 — committed to mpdude/doctrine2 by mpdude a year ago
- Add a test case to show #10348 has been fixed by #10566 This is part of the series of issues fixed by #10547. In particular, the changes from #10566 were relevant. See #10348 for the bug description... — committed to mpdude/doctrine2 by mpdude a year ago
- Add a test case to show #10348 has been fixed by #10566 This is part of the series of issues fixed by #10547. In particular, the changes from #10566 were relevant. See #10348 for the bug description... — committed to mpdude/doctrine2 by mpdude a year ago
- Add a test case to show #10348 has been fixed by #10566 This is part of the series of issues fixed by #10547. In particular, the changes from #10566 were relevant. See #10348 for the bug description... — committed to mpdude/doctrine2 by mpdude a year ago
- Merge pull request #10732 from mpdude/10348-fixed Add a test case to show #10348 has been fixed — committed to doctrine/orm by greg0ire a year ago
- Include `ON DELETE CASCADE` associations in the delete order computation (#10913) In order to resolve #10348, some changes were included in #10547 to improve the computed _delete_ order for entities.... — committed to doctrine/orm by mpdude 6 months ago
I’ve taken a closer look at this and in fact, what you’ve found here is a variant of the deletion case from #10531:
Both associations (from Child to Parent as well as from Child to Child) are
cascade: delete
, so trying to delete theParent
instance will setup the entire graph for deletion.All associations are
null
able in the database, but that’s of no relevance for the delete case, since the ORM does not currently use an “extra update” beforeDELETE
to break cycles.There is no database-level
ON DELETE SET NULL
, so the ORM will have to find a valid deletion order by itself.This is, in fact, possible by working through
Child2
,Child1
,Parent
. But, the current2.14.x
code only looks at associations at the table level, deletingchild
rows beforeparent
. It does not honor that a particular order must be followed between the entities of thechild
table itself. This is the #10531 issue, and it will be fixed by #10547.