Bug #36102
openIn 1:n relationships the parent might get lost
0%
Description
Given two classes that have a 1:n relationship modelled by means of a parent field in the child table like this:
class Parent { /** * @var Tx_Extbase_Persistence_ObjectStorage<Child> */ public $children; } class Child { /** * @var Parent */ public $parent; }
Updating the relationship can result in the child being stripped of its parent.
$newParent = $parentRepository->...; $child = $childRepository->...; $child->parent->children->remove($child), $newParent->children->add($child); $child->parent = $newParent;
This code sequence gives a consistent state in memory, but during persistAll()
, extbase will set the child's parent to NULL.
This is because extbase tries to be smart and to fix the parent field in case that the user didn't fully update the involved parties, but just added the child to its new parent.
In the above scenario, the objects are saved in this order$newParent
$child
$oldParent
- In
persistObjectStorage()
, called for$newParent
the parent field gets updated to the new parent uid. - In
persistObject()
for$child
the parent field gets updated to the new parent uid again. - In
persistObjectStorage()
for$oldParent
, the child is stripped of its parent by callingdetachObjectFromParentObject()
Thus the child becomes orphaned.
This can be worked around by means of calling persistAll()
yourself, because of another bug that causes ObjectStorages not to be marked as clean, thus they get persisted again when extbase calls persistAll()
itself, but this time the detaching won't happen, because the clean state of the parent object has been updated.