From 10ea8c05c5dadfb9675d4e17d168021ded1885b7 Mon Sep 17 00:00:00 2001 From: Adrian Brajkovic Date: Fri, 22 Mar 2024 09:45:26 +0100 Subject: [PATCH 1/3] check if foreign key is composite --- src/UnitOfWork.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index ff30f14f6d8..d4e9b5fcfd0 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -61,6 +61,7 @@ use function array_sum; use function array_values; use function assert; +use function count; use function current; use function func_get_arg; use function func_num_args; @@ -3162,8 +3163,10 @@ public function createEntity($className, array $data, &$hints = []) $reflField->setValue($entity, $pColl); if ($hints['fetchMode'][$class->name][$field] === ClassMetadata::FETCH_EAGER) { - $isIteration = isset($hints[Query::HINT_INTERNAL_ITERATION]) && $hints[Query::HINT_INTERNAL_ITERATION]; - if ($assoc['type'] === ClassMetadata::ONE_TO_MANY && ! $isIteration && ! $targetClass->isIdentifierComposite && ! isset($assoc['indexBy'])) { + $isIteration = isset($hints[Query::HINT_INTERNAL_ITERATION]) && $hints[Query::HINT_INTERNAL_ITERATION]; + $isForeignKeyComposite = count($targetClass->getAssociationMapping($assoc['mappedBy'])['joinColumns']) > 1; + + if ($assoc['type'] === ClassMetadata::ONE_TO_MANY && ! $isIteration && ! $isForeignKeyComposite && ! isset($assoc['indexBy'])) { $this->scheduleCollectionForBatchLoading($pColl, $class); } else { $this->loadCollection($pColl); From a86d234c973a1d4092962332af0b3786d4f16ae5 Mon Sep 17 00:00:00 2001 From: Adrian Brajkovic Date: Fri, 22 Mar 2024 09:45:39 +0100 Subject: [PATCH 2/3] add test --- .../RootEntity.php | 14 ++++-- .../SecondLevelWithoutCompositePrimaryKey.php | 43 +++++++++++++++++++ ...agerFetchOneToManyWithCompositeKeyTest.php | 3 +- 3 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevelWithoutCompositePrimaryKey.php diff --git a/tests/Tests/Models/EagerFetchedCompositeOneToMany/RootEntity.php b/tests/Tests/Models/EagerFetchedCompositeOneToMany/RootEntity.php index af16c686970..c804c90369c 100644 --- a/tests/Tests/Models/EagerFetchedCompositeOneToMany/RootEntity.php +++ b/tests/Tests/Models/EagerFetchedCompositeOneToMany/RootEntity.php @@ -37,11 +37,19 @@ class RootEntity */ private $secondLevel; + /** + * @ORM\OneToMany(mappedBy="root", targetEntity=SecondLevelWithoutCompositePrimaryKey::class, fetch="EAGER") + * + * @var Collection + */ + private $anotherSecondLevel; + public function __construct(int $id, string $other) { - $this->otherKey = $other; - $this->secondLevel = new ArrayCollection(); - $this->id = $id; + $this->otherKey = $other; + $this->secondLevel = new ArrayCollection(); + $this->anotherSecondLevel = new ArrayCollection(); + $this->id = $id; } public function getId(): ?int diff --git a/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevelWithoutCompositePrimaryKey.php b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevelWithoutCompositePrimaryKey.php new file mode 100644 index 00000000000..323ac52060a --- /dev/null +++ b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevelWithoutCompositePrimaryKey.php @@ -0,0 +1,43 @@ +root = $upper; + } + + public function getId(): ?int + { + return $this->id; + } +} diff --git a/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php b/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php index 82b9d0b8acb..4a3645f5e3e 100644 --- a/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php +++ b/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php @@ -6,6 +6,7 @@ use Doctrine\Tests\Models\EagerFetchedCompositeOneToMany\RootEntity; use Doctrine\Tests\Models\EagerFetchedCompositeOneToMany\SecondLevel; +use Doctrine\Tests\Models\EagerFetchedCompositeOneToMany\SecondLevelWithoutCompositePrimaryKey; use Doctrine\Tests\OrmFunctionalTestCase; final class EagerFetchOneToManyWithCompositeKeyTest extends OrmFunctionalTestCase @@ -13,7 +14,7 @@ final class EagerFetchOneToManyWithCompositeKeyTest extends OrmFunctionalTestCas /** @ticket 11154 */ public function testItDoesNotThrowAnExceptionWhenTriggeringALoad(): void { - $this->setUpEntitySchema([RootEntity::class, SecondLevel::class]); + $this->setUpEntitySchema([RootEntity::class, SecondLevel::class, SecondLevelWithoutCompositePrimaryKey::class]); $a1 = new RootEntity(1, 'A'); From 54fff9b388a36377aff79204ca70d2f02463075e Mon Sep 17 00:00:00 2001 From: Adrian Brajkovic Date: Mon, 3 Feb 2025 22:09:15 +0100 Subject: [PATCH 3/3] check if association exists --- src/UnitOfWork.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index d4e9b5fcfd0..2bcf85a5d5c 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -3164,7 +3164,7 @@ public function createEntity($className, array $data, &$hints = []) if ($hints['fetchMode'][$class->name][$field] === ClassMetadata::FETCH_EAGER) { $isIteration = isset($hints[Query::HINT_INTERNAL_ITERATION]) && $hints[Query::HINT_INTERNAL_ITERATION]; - $isForeignKeyComposite = count($targetClass->getAssociationMapping($assoc['mappedBy'])['joinColumns']) > 1; + $isForeignKeyComposite = $targetClass->hasAssociation($assoc['mappedBy']) && count($targetClass->getAssociationMapping($assoc['mappedBy'])['joinColumns']) > 1; if ($assoc['type'] === ClassMetadata::ONE_TO_MANY && ! $isIteration && ! $isForeignKeyComposite && ! isset($assoc['indexBy'])) { $this->scheduleCollectionForBatchLoading($pColl, $class);