Skip to content

Commit 4c6ae9e

Browse files
pmattmannalanpoulain
authored andcommitted
fix: prevent adding same alias twice; doctrine does not like it
1 parent 9802f4d commit 4c6ae9e

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

src/Core/Bridge/Doctrine/Orm/Extension/EagerLoadingExtension.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use Doctrine\ORM\Mapping\ClassMetadata;
3232
use Doctrine\ORM\Mapping\ClassMetadataInfo;
3333
use Doctrine\ORM\Query\Expr\Join;
34+
use Doctrine\ORM\Query\Expr\Select;
3435
use Doctrine\ORM\QueryBuilder;
3536
use Symfony\Component\HttpFoundation\RequestStack;
3637
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
@@ -264,7 +265,7 @@ private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInt
264265
continue;
265266
}
266267
} else {
267-
$queryBuilder->addSelect($associationAlias);
268+
$this->addSelectOnce($queryBuilder, $associationAlias);
268269
}
269270

270271
// Avoid recursive joins for self-referencing relations
@@ -296,7 +297,7 @@ private function addSelect(QueryBuilder $queryBuilder, string $entity, string $a
296297
$entityManager = $queryBuilder->getEntityManager();
297298
$targetClassMetadata = $entityManager->getClassMetadata($entity);
298299
if (!empty($targetClassMetadata->subClasses)) {
299-
$queryBuilder->addSelect($associationAlias);
300+
$this->addSelectOnce($queryBuilder, $associationAlias);
300301

301302
return;
302303
}
@@ -335,6 +336,17 @@ private function addSelect(QueryBuilder $queryBuilder, string $entity, string $a
335336
$queryBuilder->addSelect(sprintf('partial %s.{%s}', $associationAlias, implode(',', $select)));
336337
}
337338

339+
private function addSelectOnce(QueryBuilder $queryBuilder, string $alias)
340+
{
341+
$existingSelects = array_reduce($queryBuilder->getDQLPart('select') ?? [], function ($existing, $dqlSelect) {
342+
return ($dqlSelect instanceof Select) ? array_merge($existing, $dqlSelect->getParts()) : $existing;
343+
}, []);
344+
345+
if (!\in_array($alias, $existingSelects, true)) {
346+
$queryBuilder->addSelect($alias);
347+
}
348+
}
349+
338350
/**
339351
* Gets the serializer context.
340352
*

tests/Core/Bridge/Doctrine/Orm/Extension/EagerLoadingExtensionTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ public function testApplyToItem()
236236
$queryBuilderProphecy->addSelect('partial relatedDummy4_a5.{id}')->shouldBeCalledTimes(1);
237237
$queryBuilderProphecy->addSelect('singleInheritanceRelation_a6')->shouldBeCalledTimes(1);
238238
$queryBuilderProphecy->getDQLPart('join')->willReturn([]);
239+
$queryBuilderProphecy->getDQLPart('select')->willReturn([]);
239240

240241
$queryBuilder = $queryBuilderProphecy->reveal();
241242
$orderExtensionTest = new EagerLoadingExtension($propertyNameCollectionFactoryProphecy->reveal(), $propertyMetadataFactoryProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal(), 30, false, null, null, true);
@@ -895,6 +896,7 @@ public function testApplyToCollectionNoPartial()
895896
$queryBuilderProphecy->addSelect('relatedDummy_a1')->shouldBeCalledTimes(1);
896897
$queryBuilderProphecy->addSelect('relatedDummy2_a2')->shouldBeCalledTimes(1);
897898
$queryBuilderProphecy->getDQLPart('join')->willReturn([]);
899+
$queryBuilderProphecy->getDQLPart('select')->willReturn([]);
898900

899901
$queryBuilder = $queryBuilderProphecy->reveal();
900902
$eagerExtensionTest = new EagerLoadingExtension($propertyNameCollectionFactoryProphecy->reveal(), $propertyMetadataFactoryProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal(), 30);
@@ -960,6 +962,7 @@ private function doTestApplyToCollectionWithANonReadableButFetchEagerProperty(bo
960962
$queryBuilderProphecy->addSelect('relatedDummy_a1')->shouldBeCalledTimes(1);
961963
$queryBuilderProphecy->addSelect('relatedDummy2_a2')->shouldBeCalledTimes(1);
962964
$queryBuilderProphecy->getDQLPart('join')->willReturn([]);
965+
$queryBuilderProphecy->getDQLPart('select')->willReturn([]);
963966

964967
$queryBuilder = $queryBuilderProphecy->reveal();
965968
$eagerExtensionTest = new EagerLoadingExtension($propertyNameCollectionFactoryProphecy->reveal(), $propertyMetadataFactoryProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal(), 30);
@@ -1004,6 +1007,7 @@ public function testApplyToCollectionWithExistingJoin(string $joinType): void
10041007
new Join($joinType, 'o.relatedDummy', 'existing_join_alias'),
10051008
],
10061009
]);
1010+
$queryBuilderProphecy->getDQLPart('select')->willReturn([]);
10071011
$queryBuilderProphecy->addSelect('existing_join_alias')->shouldBeCalledTimes(1);
10081012

10091013
$queryBuilder = $queryBuilderProphecy->reveal();

0 commit comments

Comments
 (0)