Skip to content

Commit

Permalink
Bugfix: respect orderBy for fetch EAGER mode (doctrine#11163)
Browse files Browse the repository at this point in the history
Fetch EAGER mode ignores orderBy as of changes introduced with doctrine#8391
Fixes duplicated doctrine#11381
  • Loading branch information
tomr3 committed Apr 24, 2024
1 parent bdc41e2 commit 5e5af21
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/UnitOfWork.php
Original file line number Diff line number Diff line change
Expand Up @@ -3224,7 +3224,7 @@ public function triggerEagerLoads()
*
* @param PersistentCollection[] $collections
* @param array<string, mixed> $mapping
* @psalm-param array{targetEntity: class-string, sourceEntity: class-string, mappedBy: string, indexBy: string|null} $mapping
* @psalm-param array{targetEntity: class-string, sourceEntity: class-string, mappedBy: string, indexBy: string|null, orderBy: array<string, string>|null} $mapping
*/
private function eagerLoadCollections(array $collections, array $mapping): void
{
Expand All @@ -3241,7 +3241,7 @@ private function eagerLoadCollections(array $collections, array $mapping): void
$entities[] = $collection->getOwner();
}

$found = $this->getEntityPersister($targetEntity)->loadAll([$mappedBy => $entities]);
$found = $this->getEntityPersister($targetEntity)->loadAll([$mappedBy => $entities], $mapping['orderBy'] ?? null);

$targetClass = $this->em->getClassMetadata($targetEntity);
$targetProperty = $targetClass->getReflectionProperty($mappedBy);
Expand Down
135 changes: 135 additions & 0 deletions tests/Tests/ORM/Functional/Ticket/GH11163Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\PersistentCollection;
use Doctrine\Tests\OrmFunctionalTestCase;

class GH11163Test extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();

$this->setUpEntitySchema([
GH11163Bucket::class,
GH11163BucketItem::class,
]);
}

public function tearDown(): void
{
parent::tearDown();

$conn = static::$sharedConn;
$conn->executeStatement('DELETE FROM GH11163BucketItem');
$conn->executeStatement('DELETE FROM GH11163Bucket');
}

public function testFetchEagerModeWithOrderBy(): void
{
// Load entities into database
$this->_em->persist($bucket = new GH11163Bucket(11163));
$this->_em->persist(new GH11163BucketItem(1, $bucket, 2));
$this->_em->persist(new GH11163BucketItem(2, $bucket, 3));
$this->_em->persist(new GH11163BucketItem(3, $bucket, 1));
$this->_em->flush();
$this->_em->clear();

// Fetch entity from database
$dql = 'SELECT bucket FROM ' . GH11163Bucket::class . ' bucket WHERE bucket.id = :id';
$bucket = $this->_em->createQuery($dql)
->setParameter('id', 11163)
->getSingleResult();

// Assert associated entity is loaded eagerly
static::assertInstanceOf(GH11163Bucket::class, $bucket);
static::assertInstanceOf(PersistentCollection::class, $bucket->items);
static::assertTrue($bucket->items->isInitialized());

static::assertCount(3, $bucket->items);

// Assert order of entities
static::assertSame(1, $bucket->items[0]->position);
static::assertSame(3, $bucket->items[0]->id);

static::assertSame(2, $bucket->items[1]->position);
static::assertSame(1, $bucket->items[1]->id);

static::assertSame(3, $bucket->items[2]->position);
static::assertSame(2, $bucket->items[2]->id);
}
}

/**
* @ORM\Entity
*/
class GH11163Bucket
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*
* @var int
*/
private $id;

/**
* @ORM\OneToMany(
* targetEntity=GH11163BucketItem::class,
* mappedBy="bucket",
* fetch="EAGER"
* )
* @ORM\OrderBy({"position" = "ASC"})
*
* @var Collection<int, GH11163BucketItem>
*/
public $items;

public function __construct(int $id)
{
$this->id = $id;
$this->items = new ArrayCollection();
}
}

/**
* @ORM\Entity
*/
class GH11163BucketItem
{
/**
* @ORM\ManyToOne(targetEntity=GH11163Bucket::class, inversedBy="items")
* @ORM\JoinColumn(nullable=false)
*
* @var GH11163Bucket
*/
private $bucket;

/**
* @ORM\Id
* @ORM\Column(type="integer")
*
* @var int
*/
public $id;

/**
* @ORM\Column(type="integer", nullable=false)
*
* @var int
*/
public $position;

public function __construct(int $id, GH11163Bucket $bucket, int $position)
{
$this->id = $id;
$this->bucket = $bucket;
$this->position = $position;
}
}

0 comments on commit 5e5af21

Please sign in to comment.