diff --git a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php b/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php index e7d514f3be..4c7457165f 100644 --- a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php +++ b/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php @@ -465,8 +465,19 @@ public function hydrate(object $document, array $data, array $hints = []) : arra } } - if ($document instanceof GhostObjectInterface) { - $document->setProxyInitializer(null); + if ($document instanceof GhostObjectInterface && $document->getProxyInitializer() !== null) { + // Inject an empty initialiser to not load any object data + $document->setProxyInitializer(static function ( + GhostObjectInterface $ghostObject, + string $method, // we don't care + array $parameters, // we don't care + &$initializer, + array $properties // we currently do not use this + ) : bool { + $initializer = null; + + return true; + }); } $data = $this->getHydratorFor($metadata->name)->hydrate($document, $data, $hints); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php b/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php index 617b8c1f81..cf489e5076 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php +++ b/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php @@ -40,14 +40,37 @@ public function testHydrator() $this->assertEquals('jon', $user->name); $this->assertInstanceOf(DateTime::class, $user->birthdate); $this->assertInstanceOf(HydrationClosureReferenceOne::class, $user->referenceOne); + $this->assertInstanceOf(GhostObjectInterface::class, $user->referenceOne); $this->assertInstanceOf(PersistentCollection::class, $user->referenceMany); $this->assertInstanceOf(GhostObjectInterface::class, $user->referenceMany[0]); $this->assertInstanceOf(GhostObjectInterface::class, $user->referenceMany[1]); + $this->assertInstanceOf(HydrationClosureEmbedOne::class, $user->embedOne); $this->assertInstanceOf(PersistentCollection::class, $user->embedMany); $this->assertEquals('jon', $user->embedOne->name); $this->assertEquals('jon', $user->embedMany[0]->name); } + public function testHydrateProxyWithMissingAssociations() + { + $user = $this->dm->getReference(HydrationClosureUser::class, 1); + $this->assertInstanceOf(GhostObjectInterface::class, $user); + + $this->dm->getHydratorFactory()->hydrate($user, [ + '_id' => 1, + 'title' => null, + 'name' => 'jon', + ]); + + $this->assertEquals(1, $user->id); + $this->assertNull($user->title); + $this->assertEquals('jon', $user->name); + $this->assertNull($user->birthdate); + $this->assertNull($user->referenceOne); + $this->assertInstanceOf(PersistentCollection::class, $user->referenceMany); + $this->assertNull($user->embedOne); + $this->assertInstanceOf(PersistentCollection::class, $user->embedMany); + } + public function testReadOnly() { $class = $this->dm->getClassMetadata(HydrationClosureUser::class);