Skip to content

Commit 8245544

Browse files
carlobeltramealanpoulain
authored andcommitted
feat: Avoid eager joining back to the just visited parent
1 parent 594e4bf commit 8245544

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use ApiPlatform\Exception\RuntimeException;
2929
use ApiPlatform\Metadata\ApiProperty;
3030
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
31+
use Doctrine\ORM\Mapping\ClassMetadata;
3132
use Doctrine\ORM\Mapping\ClassMetadataInfo;
3233
use Doctrine\ORM\Query\Expr\Join;
3334
use Doctrine\ORM\QueryBuilder;
@@ -167,7 +168,7 @@ private function apply(bool $collection, QueryBuilder $queryBuilder, QueryNameGe
167168
*
168169
* @throws RuntimeException when the max number of joins has been reached
169170
*/
170-
private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, bool $forceEager, bool $fetchPartial, string $parentAlias, array $options = [], array $normalizationContext = [], bool $wasLeftJoin = false, int &$joinCount = 0, int $currentDepth = null)
171+
private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, bool $forceEager, bool $fetchPartial, string $parentAlias, array $options = [], array $normalizationContext = [], bool $wasLeftJoin = false, int &$joinCount = 0, int $currentDepth = null, string $parentAssociation = null)
171172
{
172173
if ($joinCount > $this->maxJoins) {
173174
throw new RuntimeException('The total number of joined relations has exceeded the specified maximum. Raise the limit if necessary with the "api_platform.eager_loading.max_joins" configuration key (https://api-platform.com/docs/core/performance/#eager-loading), or limit the maximum serialization depth using the "enable_max_depth" option of the Symfony serializer (https://symfony.com/doc/current/components/serializer.html#handling-serialization-depth).');
@@ -232,6 +233,16 @@ private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInt
232233
continue;
233234
}
234235

236+
// Avoid joining back to the parent that we just came from, but only on *ToOne relations
237+
if (
238+
null !== $parentAssociation &&
239+
isset($mapping['inversedBy']) &&
240+
$mapping['inversedBy'] === $parentAssociation &&
241+
$mapping['type'] & ClassMetadata::TO_ONE
242+
) {
243+
continue;
244+
}
245+
235246
$existingJoin = QueryBuilderHelper::getExistingJoin($queryBuilder, $parentAlias, $association);
236247

237248
if (null !== $existingJoin) {
@@ -276,7 +287,7 @@ private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInt
276287
}
277288
}
278289

279-
$this->joinRelations($queryBuilder, $queryNameGenerator, $mapping['targetEntity'], $forceEager, $fetchPartial, $associationAlias, $options, $childNormalizationContext, $isLeftJoin, $joinCount, $currentDepth);
290+
$this->joinRelations($queryBuilder, $queryNameGenerator, $mapping['targetEntity'], $forceEager, $fetchPartial, $associationAlias, $options, $childNormalizationContext, $isLeftJoin, $joinCount, $currentDepth, $association);
280291
}
281292
}
282293

0 commit comments

Comments
 (0)