@@ -246,9 +246,14 @@ public function testCompositeIdentifiers()
246
246
$ resourceMetadataFactoryProphecy = $ this ->prophesize (ResourceMetadataFactoryInterface::class);
247
247
$ resourceMetadataFactoryProphecy ->create (CompositeRelation::class)->willReturn (new ResourceMetadata (CompositeRelation::class));
248
248
249
- $ classMetadata = new ClassMetadataInfo (CompositeRelation::class);
249
+ $ classMetadataProphecy = $ this ->prophesize (ClassMetadataInfo::class);
250
+ $ classMetadataProphecy ->getIdentifier ()->willReturn (['item ' , 'label ' ]);
251
+ $ classMetadataProphecy ->getAssociationMappings ()->willReturn (['item ' => ['fetch ' => ClassMetadataInfo::FETCH_EAGER ]]);
252
+ $ classMetadataProphecy ->hasAssociation ('item ' )->shouldBeCalled ()->willReturn (true );
253
+ $ classMetadataProphecy ->hasAssociation ('label ' )->shouldBeCalled ()->willReturn (true );
254
+
255
+ $ classMetadata = $ classMetadataProphecy ->reveal ();
250
256
$ classMetadata ->isIdentifierComposite = true ;
251
- $ classMetadata ->identifier = ['item ' , 'label ' ];
252
257
253
258
$ em = $ this ->prophesize (EntityManager::class);
254
259
$ em ->getExpressionBuilder ()->shouldBeCalled ()->willReturn (new Expr ());
@@ -353,6 +358,64 @@ public function testFetchEagerWithNoForceEager()
353
358
$ this ->assertEquals ($ this ->toDQLString ($ expected ), $ qb ->getDQL ());
354
359
}
355
360
361
+ public function testCompositeIdentifiersWithoutAssociation ()
362
+ {
363
+ $ resourceMetadataFactoryProphecy = $ this ->prophesize (ResourceMetadataFactoryInterface::class);
364
+ $ resourceMetadataFactoryProphecy ->create (CompositeRelation::class)->willReturn (new ResourceMetadata (CompositeRelation::class));
365
+
366
+ $ classMetadataProphecy = $ this ->prophesize (ClassMetadataInfo::class);
367
+ $ classMetadataProphecy ->getIdentifier ()->willReturn (['item ' , 'label ' , 'bar ' ]);
368
+ $ classMetadataProphecy ->getAssociationMappings ()->willReturn (['item ' => ['fetch ' => ClassMetadataInfo::FETCH_EAGER ]]);
369
+ $ classMetadataProphecy ->hasAssociation ('item ' )->shouldBeCalled ()->willReturn (true );
370
+ $ classMetadataProphecy ->hasAssociation ('label ' )->shouldBeCalled ()->willReturn (true );
371
+ $ classMetadataProphecy ->hasAssociation ('bar ' )->shouldBeCalled ()->willReturn (false );
372
+
373
+ $ classMetadata = $ classMetadataProphecy ->reveal ();
374
+ $ classMetadata ->isIdentifierComposite = true ;
375
+
376
+ $ em = $ this ->prophesize (EntityManager::class);
377
+ $ em ->getExpressionBuilder ()->shouldBeCalled ()->willReturn (new Expr ());
378
+ $ em ->getClassMetadata (CompositeRelation::class)->shouldBeCalled ()->willReturn ($ classMetadata );
379
+
380
+ $ qb = new QueryBuilder ($ em ->reveal ());
381
+
382
+ $ qb ->select ('o ' )
383
+ ->from (CompositeRelation::class, 'o ' )
384
+ ->innerJoin ('o.compositeItem ' , 'item ' )
385
+ ->innerJoin ('o.compositeLabel ' , 'label ' )
386
+ ->where ('item.field1 = :foo AND o.bar = :bar ' )
387
+ ->setParameter ('foo ' , 1 )
388
+ ->setParameter ('bar ' , 2 );
389
+
390
+ $ queryNameGenerator = $ this ->prophesize (QueryNameGeneratorInterface::class);
391
+ $ queryNameGenerator ->generateJoinAlias ('item ' )->shouldBeCalled ()->willReturn ('item_2 ' );
392
+ $ queryNameGenerator ->generateJoinAlias ('label ' )->shouldBeCalled ()->willReturn ('label_2 ' );
393
+ $ queryNameGenerator ->generateJoinAlias ('o ' )->shouldBeCalled ()->willReturn ('o_2 ' );
394
+
395
+ $ filterEagerLoadingExtension = new FilterEagerLoadingExtension ($ resourceMetadataFactoryProphecy ->reveal (), true );
396
+ $ filterEagerLoadingExtension ->applyToCollection ($ qb , $ queryNameGenerator ->reveal (), CompositeRelation::class, 'get ' );
397
+
398
+ $ expected = <<<SQL
399
+ SELECT o
400
+ FROM ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeRelation o
401
+ INNER JOIN o.compositeItem item
402
+ INNER JOIN o.compositeLabel label
403
+ WHERE (o.item IN(
404
+ SELECT IDENTITY(o_2.item) FROM ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeRelation o_2
405
+ INNER JOIN o_2.compositeItem item_2
406
+ INNER JOIN o_2.compositeLabel label_2
407
+ WHERE item_2.field1 = :foo AND o_2.bar = :bar
408
+ )) AND (o.label IN(
409
+ SELECT IDENTITY(o_2.label) FROM ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeRelation o_2
410
+ INNER JOIN o_2.compositeItem item_2
411
+ INNER JOIN o_2.compositeLabel label_2
412
+ WHERE item_2.field1 = :foo AND o_2.bar = :bar
413
+ ))
414
+ SQL ;
415
+
416
+ $ this ->assertEquals ($ this ->toDQLString ($ expected ), $ qb ->getDQL ());
417
+ }
418
+
356
419
private function toDQLString (string $ dql ): string
357
420
{
358
421
return preg_replace (['/\s+/ ' , '/\(\s/ ' , '/\s\)/ ' ], [' ' , '( ' , ') ' ], $ dql );
0 commit comments