mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Cascade deletion complicate-referenced entities does not work [ForeignKeyConstraintViolationException] #5018
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 @mtal on GitHub (Feb 14, 2016).
Originally assigned to: @guilhermeblanco on GitHub.
is caused by
Entity mappings:
@Ocramius commented on GitHub (Feb 14, 2016):
Seems normal to me:
$em->remove($item);item now marked for removal$em->flush();tries to delete the item, but it is still referenced by sub-items, which recursively are referenced byItem#featuredItemIn this scenario, you need to define a DB-level cascade operation via the
@JoinColumn(onDelete="CASCADE")mapping.@mtal commented on GitHub (Feb 14, 2016):
DB-level cascade will not trigger lifecycle events.
If this scenario seem normal to you, I could give you another
Before marking item for deletion with
$em->remove($item);manually delete subitems by$em->remove($sub1)and$em->remove($sub2)or by orphan ($item->removeItem($sub1); $item->removeItem($sub2);)The flush is still throw ForeignKeyConstraintViolationException.
Entities cannot be removed at ORM level without calling flush more than 1 time. Is this normal?
@Ocramius commented on GitHub (Feb 14, 2016):
Indeed, but a delete with a cascade won't trigger any deletes until mid-flush, so lifecycle events on some cascaded items will still work (first level of cascading)
@Ocramius commented on GitHub (Feb 14, 2016):
You have a cyclic constraint there: that's not something the ORM can solve for you right now
@mtal commented on GitHub (Feb 14, 2016):
But it solve insertions properly by preassigning NULL in INSERT query and assigning generated identy in update query.
So it should do the same at deletion in reverse order. Update column to NULL before deleting.
@Ocramius commented on GitHub (Feb 14, 2016):
That isn't currently done by the ORM as far as I know (I would have to check the test suite, but no time ATM), mostly because the column may be non-nullable
@mtal commented on GitHub (Feb 14, 2016):
In this case it is impossible. If it is non-nullable you cannot insert cyclic referenced entity. So first flush for persisting will fail.
@Ocramius commented on GitHub (Feb 14, 2016):
Good point indeed. I suggest digging in the existing test suite for similar cases though, as this behavior may indeed be improved.
@guilhermeblanco commented on GitHub (Feb 15, 2016):
@mtal I'd ask you to try the same case using latest master.
I refactored the
CommitOrderCalculatorwhich should address the cyclic insertion. There's one use case though that was not covered (as it was way too hard to address and test), and I wanna confirm this is the same case you just found out.I also implemented a couple changes in the OrphanRemoval that should properly remove orphaned on *ToMany and might be related.
Can you please test this against master and comment back? We might extract a sample TestCase from this for us to look if both situations didn't cover your issue.
@mtal commented on GitHub (Feb 16, 2016):
Delete order is changed but issue is still persist. Exception is still thrown.
The commit order cannot fix it. Before deleting row, another that references it, must be updated. Referencing column must be updated to null.
The cyclic insertion was work properly before. The issue in impossibility to delete inside single flush.
@mtal commented on GitHub (Feb 16, 2016):
And without actual (persisted cyclic references) deletion still fails. Commit order calculated incorrectly.
Look at this case:
Exception
[Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException] An exception occurred while executing 'DELETE FROM item WHERE id = ?' with params [3]: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or upda te a parent row: a foreign key constraint fails (shop.subitem, CONSTRAI NTFK_C6AE5795126F525EFOREIGN KEY (item_id) REFERENCESitem(id))The database log
The 'subitem' and 'subsubitem' must be deleted before
item.Mapping:
@idchlife commented on GitHub (Sep 19, 2016):
Guys, any info on resolving this issue? I have user->galleries->photos->images and I have foreign key constraint error mentioned in topic when trying to remove user.
I should make onDelete="CASCADE" in this case or remove everything by hand?
UPDATE: onDelete="CASCADE" does not event make difference for migration to database, so I cannot use this.
@slince commented on GitHub (Dec 12, 2017):
up
@Ocramius commented on GitHub (Dec 12, 2017):
@slince that doesn't help - open a PR with a reproducible failing test case
@slince commented on GitHub (Dec 12, 2017):
@Ocramius
Hi, the problem I encountered is the same as this one
@Ocramius commented on GitHub (Dec 12, 2017):
@slince yes, but upvoting doesn't get anywhere on a project without dedicated staff. You gotta help yourself too ;-)
@wilariz commented on GitHub (Oct 15, 2018):
Hi, are there a solution for this problem? recently I update mi libraries and a update process trigger this error.
Checking the class UnitOfWork, I have the list of entities to delete ( var $collectionDeletions), in mi case I have 3 entities(a parent and two children), the problem that I found is in the order to delete, it try to delete the parent first, and children after, it acoording to the order of the list.
my mapping aparently is ok, "persist" and "remove" from owner and onDelete:Cascade from other side.
Any idea about solution?
@mpdude commented on GitHub (Feb 28, 2023):
Update 2023:
To summarize what has been written above, the problem is not finding an insert order for the cyclic associations. The UoW is able to solve this by scheduling "extra updates". This is possible since all associations are NULLable (by default!).
The problem lies in the DELETE operation, where the ORM does currently not schedule extra updates before the DELETE to break association cycles.
A failing test showing the lack of this feature can be found in #10548.
But even when the user configures
@JoinColumn(onDelete="CASCADE")]to make the DBMS null out the foreign keys, it is important that the commit order takes this into consideration and schedules deletions appropriately. It is not currently doing this, which is demonstrated in #10566.@mpdude commented on GitHub (Oct 8, 2024):
Update 2024:
The ORM is not (yet?) able to perform extra
UPDATEs to NULL out associations referring to entities that are about to be removed; but, a database-levelON DELETE SET NULLcan be used for that.Since #10566, the ORM should schedule removals in the appropriate order.