diff --git a/src/Internal/Hydration/ObjectHydrator.php b/src/Internal/Hydration/ObjectHydrator.php index a5d97d30966..c01496a5ca8 100644 --- a/src/Internal/Hydration/ObjectHydrator.php +++ b/src/Internal/Hydration/ObjectHydrator.php @@ -367,11 +367,15 @@ protected function hydrateRowData(array $row, array &$result) $parentObject = $this->resultPointers[$parentAlias]; } else { // Parent object of relation not found, mark as not-fetched again - $element = $this->getEntity($data, $dqlAlias); + if (isset($nonemptyComponents[$dqlAlias])) { + $element = $this->getEntity($data, $dqlAlias); - // Update result pointer and provide initial fetch data for parent - $this->resultPointers[$dqlAlias] = $element; - $rowData['data'][$parentAlias][$relationField] = $element; + // Update result pointer and provide initial fetch data for parent + $this->resultPointers[$dqlAlias] = $element; + $rowData['data'][$parentAlias][$relationField] = $element; + } else { + $element = null; + } // Mark as not-fetched again unset($this->_hints['fetched'][$parentAlias][$relationField]); diff --git a/tests/Tests/ORM/Functional/Ticket/GH10889Test.php b/tests/Tests/ORM/Functional/Ticket/GH10889Test.php new file mode 100644 index 00000000000..eebdc100666 --- /dev/null +++ b/tests/Tests/ORM/Functional/Ticket/GH10889Test.php @@ -0,0 +1,107 @@ +createSchemaForModels( + GH10889User::class, + GH10889Finger::class, + GH10889Hand::class + ); + } + + public function testIssue(): void + { + $user = new GH10889User(); + $hand = new GH10889Hand($user, null); + + $this->_em->persist($user); + $this->_em->persist($hand); + $this->_em->flush(); + $this->_em->clear(); + + /** @var list $hands */ + $hands = $this->_em + ->getRepository(GH10889Hand::class) + ->createQueryBuilder('hand') + ->leftJoin('hand.thumb', 'thumb')->addSelect('thumb') + ->getQuery() + ->getResult(); + + $this->assertArrayHasKey(0, $hands); + $this->assertEquals(1, $hands[0]->user->id); + $this->assertNull($hands[0]->thumb); + } +} + +/** + * @ORM\Entity + */ +class GH10889User +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + public $id; +} + +/** + * @ORM\Entity + */ +class GH10889Finger +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + public $id; +} + +/** + * @ORM\Entity + */ +class GH10889Hand +{ + /** + * @ORM\Id + * @ORM\OneToOne(targetEntity="GH10889User") + * + * @var GH10889User + */ + public $user; + + /** + * @ORM\ManyToOne(targetEntity="GH10889Finger") + * + * @var GH10889Finger|null + */ + public $thumb; + + public function __construct(GH10889User $user, ?GH10889Finger $thumb) + { + $this->user = $user; + $this->thumb = $thumb; + } +}