Unexpected INSERT when replacing collection of B with another one after persisting A. #6460

Open
opened 2026-01-22 15:33:38 +01:00 by admin · 1 comment
Owner

Originally created by @danydev on GitHub (May 9, 2020).

Bug Report

Q A
BC Break no
Version tested on branch 2.7, likely everywhere else

Summary

In our project we encountered an error about breaking a database constraint. That happened because Doctrine wrongly decided to do an INSERT that should have not happened.
Specifically we had two classes: ClassA, ClassB. ClassA has a property 'classesB' that is a bidirectional OneToMany to ClassB with cascade persist and orphanRemoval.

  1. Create an object of ClassA.
  2. Create an object of ClassB.
  3. Put object of ClassB in the 'classesB' collection (property of ClassA object).
  4. Persist object of ClassA.
  5. Then some logic resulted in 'classesB' collection being emptied and then filled with a new object of ClassB.
  6. Finally the flush. At this point Doctrine correctly does the INSERT for the object of ClassB that was added in the collection in step 5 but it also does the INSERT for the object created in the step 2 (that should have not been happened because replaced in step 5).

Current behaviour

Doctrine produced an unexpected INSERT that should not have occurred (specifically the INSERT for the object of ClassB but that really was replaced in the collection, and thus should not be persisted at all in the database).
I understand that what probably happens is that the persist schedules the object in its inserts because of the cascade persist, but still my expectation is that such object would be unscheduled given later has been removed from the collection. Let's say that 'orphanRemoval' would normally delete it from the DB, and in this case I expect is that it should cause the unschedule from the UoW.

How to reproduce

Functional test in this PR
https://github.com/doctrine/orm/pull/8134/files

Expected behaviour

The INSERT for the object that has been replaced in the collection should not occur.

Workaround

If we move the persist for object of ClassA after replacing the collection (i.e. after step 5), then it works as expected, and only the correct INSERT is performed.
So let's say that you can always re-arrange your code to avoid the bug by setting the collection only once before doing the persist, but still I think it's a legit bug.

Originally created by @danydev on GitHub (May 9, 2020). ### Bug Report | Q | A |------------ | ------ | BC Break | no | Version | tested on branch 2.7, likely everywhere else #### Summary In our project we encountered an error about breaking a database constraint. That happened because Doctrine wrongly decided to do an INSERT that should have not happened. Specifically we had two classes: ClassA, ClassB. ClassA has a property 'classesB' that is a bidirectional OneToMany to ClassB with cascade persist and orphanRemoval. 1. Create an object of ClassA. 2. Create an object of ClassB. 3. Put object of ClassB in the 'classesB' collection (property of ClassA object). 4. Persist object of ClassA. 5. Then some logic resulted in 'classesB' collection being emptied and then filled with a new object of ClassB. 6. Finally the flush. At this point Doctrine correctly does the INSERT for the object of ClassB that was added in the collection in step 5 but it also does the INSERT for the object created in the step 2 (that should have not been happened because replaced in step 5). #### Current behaviour Doctrine produced an unexpected INSERT that should not have occurred (specifically the INSERT for the object of ClassB but that really was replaced in the collection, and thus should not be persisted at all in the database). I understand that what probably happens is that the persist schedules the object in its inserts because of the cascade persist, but still my expectation is that such object would be unscheduled given later has been removed from the collection. Let's say that 'orphanRemoval' would normally delete it from the DB, and in this case I expect is that it should cause the unschedule from the UoW. #### How to reproduce Functional test in this PR https://github.com/doctrine/orm/pull/8134/files #### Expected behaviour The INSERT for the object that has been replaced in the collection should not occur. #### Workaround If we move the persist for object of ClassA **after** replacing the collection (i.e. after step 5), then it works as expected, and only the correct INSERT is performed. So let's say that you can always re-arrange your code to avoid the bug by setting the collection only once before doing the persist, but still I think it's a legit bug.
Author
Owner

@mougrim commented on GitHub (Jan 25, 2021):

Have the same issue, also reproduced with OneToOne relations.

@mougrim commented on GitHub (Jan 25, 2021): Have the same issue, also reproduced with OneToOne relations.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6460