mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
OrphanRemoval doesn't work if set new collection without explicit remove() #5463
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 @benbor on GitHub (Mar 15, 2017).
I've relations OneToMany and I want to bulk update all tags (I want to delete few tags and add other few) for one post
Expected:
Doctrine saves Post#1 with Tag#1 (tag witch doesn't changed), Tag#3 (new tag)
Actual:
Doctrine saves Post#1 with Tag#1, Tag#2, Tag#3
My hot fix:
before set new collection I explicit remove tags, which should be removed
And all works fine! Creating and deleting works fine. (Editing another fields like "name" also works fine)
What is My question? Why doctrine can't do it self? I'm sure orphanRemoval option should delete it self.
My entities:
@Ocramius commented on GitHub (Mar 15, 2017):
Replacing collection instances is not really fully supported, although the bug looks legit. Calling
clear()on the original collection would probably cause chaos though...@benbor commented on GitHub (Mar 15, 2017):
@Ocramius method
clear()didn't help me.It saves only Post#1 and doesn't save Tags at all .
@alsma commented on GitHub (Mar 16, 2017):
I've also met similar issue today:
new tag is scheduled for orphan removal, and not inserted
@lcobucci commented on GitHub (Mar 16, 2017):
As @Ocramius said, replacing the collection is not supported (and it would never work since the information regarding orphan removals is on
PersistentCollectionclass). HoweverCollection#clear()+Collection#add()does the job, I just ran this test onmasterand everything works:@lcobucci commented on GitHub (Mar 16, 2017):
I do agree that replacing the whole collection is something nice to have but I'd say that it should be only supported/considered on v3 after the refactor that @guilhermeblanco is doing
@benbor commented on GitHub (Mar 16, 2017):
@lcobucci thanks for the answer.
Your test isn't full for my case. If you will add few already exists Tags after
$post->tags->clear()they will be lost. Bug reproduced only for last stable branch(at now 2.5), formasterbranch it behavior already fixed and everything works well.Would be great to fix it case for stable branch too.
Gist with my test. I specified the test environment in comments.
@guilhermeblanco commented on GitHub (Mar 16, 2017):
@benbor Not an easy fix to be backported, as it introduces a BC break...
The commit that fixes this is here:
1587aac4ffThis should be part of 2.6 but I cannot classify this as a "bug" of 2.5, since it introduces a new behavior to OneToMany.
@benbor commented on GitHub (Mar 17, 2017):
@guilhermeblanco from my point of view old tag losing after clear() is pure "bug"
Why this case doesn't work for version 2.5 ? imho its obvious bug.
@wadjeroudi commented on GitHub (Jan 12, 2018):
"I do agree that replacing the whole collection is something nice to have but I'd say that it should be only supported/considered on v3 after the refactor that @guilhermeblanco is doing"
@lcobucci Is it still planned for v3 ?
The issue should be closed as 2.6 has been released ?
@Ocramius commented on GitHub (Jan 12, 2018):
If someone wants to implement that, they'd need to pick up the work themselves. Starting from a test would already be great.
The core team already has enough WIP areas for now.
@wadjeroudi commented on GitHub (Jan 12, 2018):
@Ocramius in my opinion the orphanRemoval is a weird implementation to do a simple task : remove element.
The "natural" and "logical" way to remove an entity from a collection should be just to call remove/removeElement from this collection.
Without setting the parent entity to null.
Is there a possible implementation of this behaviour and would it be accepted ? If yes, I may try to implement it.
@NavyCoat commented on GitHub (Jan 12, 2018):
@wadjeroudi I'm not the "oldest" developer and in my first days/months :), Doctrine looks like big and strange piece of code that do a lot of magic. And it has strange thing. For example this removing elements behaviour. For me as user of this package, I expected it will remove element :P
@Ocramius commented on GitHub (Jan 12, 2018):
As already mentioned, write a test case first. Discussion should start from the test expectations.
@mattsah commented on GitHub (Apr 11, 2019):
I'm not sure if this is related to this. But we had a long working piece of software that would replace collections with new collections outright. The new collection might have a mix of the same entities as the old, some removed, or even some new ones added. Or, if nothing changed, the new collection might have exactly the same entities.
At some point (still trying to determine what version, currently on 2.6.3) this stopped working. We were receiving an exception because doctrine was trying to remove the related record and it was still being referenced by other entities. We were not changing any of the associated entities, they were simply being added to a new collection, and the collection was being replaced outright.
From what I can tell doctrine is seeing the entities as orphaned because of this and it was trying to remove the entities. Thankfully, this was causing an exception due to other relations and foreign key constraints. When I set orphan removal to false, everything worked as expected again (but obviously I wouldn't expected the orphans to be removed).