mirror of
https://github.com/doctrine/orm.git
synced 2026-03-23 22:42:18 +01:00
Order of referenced child deletions not correct when referencing to itself #7085
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Toflar on GitHub (Dec 29, 2022).
Bug Report
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
cascade: ['remove']cascade: ['remove'].Now you delete the parent.
Doctrine tries to remove Child 1 first instead of Child 2 causing a foreign constraint violation:
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:
composer installbootstrap.php.bin/doctrine orm:schema-tool:drop --force && bin/doctrine orm:schema-tool:createphp test.php.Expected behavior
It should not throw an exception. Doctrine should remove Child 2 first.
@simonberger commented on GitHub (Jan 2, 2023):
This test is based on @Toflar ' s reproducer and can be picked up:
2abff4cce5I could also create a PR if requested. It fails with mysql but works with sqlite. I didn't test further.
It is no new bug and happened also in 2.11.
@Toflar commented on GitHub (Jan 2, 2023):
Thanks <3 Maybe sqlite is configured without foreign key support in the CI? 🤔
@simonberger commented on GitHub (Jan 2, 2023):
I just tested local on mac. This could be the reason. Maybe it even fails in CI. :)
I am interested to know and created the PR. We can close it again after seeing the results.
EDIT:
Sqlite succeeds also in the CI. MariaDB, PostgreSQL and MySQL all fail.
@mpdude commented on GitHub (Feb 27, 2023):
@Toflar could you please have a look at #10547?
I am not too confident it might fix this issue here, since I do not know if all the entities that need to be cascade-deleted are put into the
\Doctrine\ORM\UnitOfWork::$entityDeletionslist before the commit order is computed.But anyway, you might want to give it a shot.
@mpdude commented on GitHub (Feb 28, 2023):
Ah, maybe this is #10548?
@Toflar commented on GitHub (Feb 28, 2023):
Hey @mpdude wow, the other PR is some impressive work! Maybe we can pick up @simonberger's reproducer (
2abff4cce5) in the CI as well, then we know if your PR fixes the problem :)@simonberger commented on GitHub (Mar 5, 2023):
@mpdude Looks good that this issue is covered by your fix. I ran the tests on your branch and it succeeded.
I created a PR on your branch or just add it manually if you like.
https://github.com/mpdude/doctrine2/pull/2
@mpdude commented on GitHub (Mar 5, 2023):
That's great news, although I am not sure if that's by incident. But I have this issue on my shortlist and think it can be fixed as well.
For the delete case, we need not look out for nullable associations (like we do at insert time), but find the associations that use
SET NULLas candidates for breaking cycles.@simonberger commented on GitHub (Mar 5, 2023):
While I don't have much knowledge about the implementation, the test at least looked senseful to me and should have some validity.
@mpdude commented on GitHub (Mar 5, 2023):
Definitely, it is! I did not want to put that into question, sorry if it sounded like that.
My thinking was that I see another problematic case pointed out by this issue here, and I think #10547 does not address this precisely enough. I’ll see if I can fine-tune the test a little to make it fail until that situation is addressed as well.
Thank you for the PR against my branch, that helps.
@simonberger commented on GitHub (Mar 5, 2023):
I also didn't read it like this and the tests are from toflar, I just converted them to phpunit.
@mpdude commented on GitHub (Mar 6, 2023):
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 theParentinstance will setup the entire graph for deletion.All associations are
nullable in the database, but that's of no relevance for the delete case, since the ORM does not currently use an "extra update" beforeDELETEto 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.xcode only looks at associations at the table level, deletingchildrows beforeparent. It does not honor that a particular order must be followed between the entities of thechildtable itself. This is the #10531 issue, and it will be fixed by #10547.@Toflar commented on GitHub (Mar 6, 2023):
Wohoo! Thanks so much for the investigation and the awesome work - that PR seems to solve a lot of issues! Kudos @mpdude! Let's hope your work can make it to a release soon!
@mpdude commented on GitHub (Mar 6, 2023):
Test case included at
3917692ff8@mpdude commented on GitHub (Mar 6, 2023):
Indeed there is another bug regarding the delete order, which I have filed as #10566