mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Bidirectional OneToOne with orphanRemoval leads to the deletion of a still referenced entity #6610
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 @NoiseByNorthwest on GitHub (Jan 22, 2021).
I have 2 entity types, say
A&B.A->bis a bidirectional OneToOne relationship withBand inversed byB->a.As the owning side,
A->bis configured with "cascade persist" & "orphanRemoval".What happens when flushing the entity manager after having changed
A#1->bfromB#1(STATE_MANAGED) toB#2(STATE_NEW):A#1->bis considered to have changed fromB#1toB#2B#2is now considered to be the original value ofA#1->b: https://github.com/doctrine/orm/blob/2.8.1/lib/Doctrine/ORM/UnitOfWork.php#L781B#1is now an orphan, it is removed from the UoW: https://github.com/doctrine/orm/blob/2.8.1/lib/Doctrine/ORM/UnitOfWork.php#L371B#1->cbeing itself a relationship with "cascade remove",B#1must be traversed: https://github.com/doctrine/orm/blob/2.8.1/lib/Doctrine/ORM/UnitOfWork.php#L2386B#1being a proxy, it must be first loaded: https://github.com/doctrine/orm/blob/2.8.1/lib/Doctrine/ORM/UnitOfWork.php#L2393B#1->a(A#1->b's inverse side) is also loaded, since Inverse side of x-to-one can never be lazy: https://github.com/doctrine/orm/blob/2.8.1/lib/Doctrine/ORM/UnitOfWork.php#L2735A#1->bis overwritten withB#1: https://github.com/doctrine/orm/blob/2.8.1/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php#L805This is IMO unexpected, I do not understand this behavior which is furthermore the root cause of this issue.
Why the owning entity must be touched in this case ?
A#1->bhasB#1as value andB#2being considered as its original value, it is then wrongly considered to have changed fromB#2toB#1A#1is updated withB#1asA#1->b's new value, which is actually already its current value: https://github.com/doctrine/orm/blob/2.8.1/lib/Doctrine/ORM/UnitOfWork.php#L1181B#1is deleted while still being referenced byA#1->b, causing aForeignKeyConstraintViolationException: https://github.com/doctrine/orm/blob/2.8.1/lib/Doctrine/ORM/UnitOfWork.php#L1210Am I doing something wrong / illegal here or is it a bug ?
Workaround: Since the root cause seems to be derived from the load of
B#1during the commit, my current workaround is simply to preloadA#1->bat query time, ahead of the business logic & flush.