From 97a7cb8d2f72c56bb027154b476d7f31aa28f5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Thu, 8 May 2025 00:49:09 +0200 Subject: [PATCH] Unify JoinedSubclassPersister dequeue Fix JoinedSubclassPersister as BasicEntityPersister was already fixed in GH-10735. The fix can be verified by modifying UnitOfWork to execute `BasicEntityPersister::executeInserts()` for multiple entities at once for the same entity class/persister instance - https://github.com/doctrine/orm/blob/2.20.3/src/UnitOfWork.php#L1186 - then reproducible on `Doctrine\Tests\ORM\Functional\Ticket\GH10531Test::testInserts` test. As extending/modifying UnitOfWork in tests in not easily possible, I submit this fix for v2.x without a test. --- src/Persisters/Entity/BasicEntityPersister.php | 4 ++-- src/Persisters/Entity/JoinedSubclassPersister.php | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Persisters/Entity/BasicEntityPersister.php b/src/Persisters/Entity/BasicEntityPersister.php index f30f223fd5b..289d0759699 100644 --- a/src/Persisters/Entity/BasicEntityPersister.php +++ b/src/Persisters/Entity/BasicEntityPersister.php @@ -302,8 +302,8 @@ public function executeInserts() $this->assignDefaultVersionAndUpsertableValues($entity, $id); } - // Unset this queued insert, so that the prepareUpdateData() method knows right away - // (for the next entity already) that the current entity has been written to the database + // Unset this queued insert, so that the prepareUpdateData() method (called via prepareInsertData() method) + // knows right away (for the next entity already) that the current entity has been written to the database // and no extra updates need to be scheduled to refer to it. // // In \Doctrine\ORM\UnitOfWork::executeInserts(), the UoW already removed entities diff --git a/src/Persisters/Entity/JoinedSubclassPersister.php b/src/Persisters/Entity/JoinedSubclassPersister.php index 5a7807b6343..e7d83343fe8 100644 --- a/src/Persisters/Entity/JoinedSubclassPersister.php +++ b/src/Persisters/Entity/JoinedSubclassPersister.php @@ -149,7 +149,7 @@ public function executeInserts() // Execute all inserts. For each entity: // 1) Insert on root table // 2) Insert on sub tables - foreach ($this->queuedInserts as $entity) { + foreach ($this->queuedInserts as $key => $entity) { $insertData = $this->prepareInsertData($entity); // Execute insert on root table @@ -194,9 +194,16 @@ public function executeInserts() if ($this->class->requiresFetchAfterChange) { $this->assignDefaultVersionAndUpsertableValues($entity, $id); } - } - $this->queuedInserts = []; + // Unset this queued insert, so that the prepareUpdateData() method (called via prepareInsertData() method) + // knows right away (for the next entity already) that the current entity has been written to the database + // and no extra updates need to be scheduled to refer to it. + // + // In \Doctrine\ORM\UnitOfWork::executeInserts(), the UoW already removed entities + // from its own list (\Doctrine\ORM\UnitOfWork::$entityInsertions) right after they + // were given to our addInsert() method. + unset($this->queuedInserts[$key]); + } } /**