diff --git a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php b/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php index a182d3963..e5ac3ce7f 100644 --- a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php +++ b/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php @@ -185,10 +185,10 @@ private function generateHydratorClass(ClassMetadata $class, string $hydratorCla <<<'EOF' // Field(type: "date") - if (isset($data['%1$s'])) { + if (array_key_exists('%1$s', $data) && ($data['%1$s'] !== null || ($this->class->fieldMappings['%2$s']['nullable'] ?? false))) { $value = $data['%1$s']; %3$s - $this->class->reflFields['%2$s']->setValue($document, clone $return); + $this->class->reflFields['%2$s']->setValue($document, $return === null ? null : clone $return); $hydratedData['%2$s'] = $return; } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/DateTest.php b/tests/Doctrine/ODM/MongoDB/Tests/Functional/DateTest.php index 35aa83b83..2e1b140de 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/DateTest.php +++ b/tests/Doctrine/ODM/MongoDB/Tests/Functional/DateTest.php @@ -84,6 +84,19 @@ public function testDateInstanceChangeWhenValueDifferenceIsSubSecond(): void self::assertNotEmpty($changeset); } + public function testNullableDateInstanceValue(): void + { + $user = new User(); + $user->setCreatedAt(new DateTime('1985-09-01')); + $this->dm->persist($user); + $this->dm->flush(); + $this->dm->clear(); + + $user = $this->dm->getRepository($user::class)->findOneBy([]); + self::assertInstanceOf(DateTime::class, $user->getCreatedAt()); + self::assertNull($user->getDisabledAt()); + } + public function testDateInstanceValueChangeDoesCauseUpdateIfValueIsTheSame(): void { $user = new User(); diff --git a/tests/Documents/User.php b/tests/Documents/User.php index f7ea6f859..7e1031ec3 100644 --- a/tests/Documents/User.php +++ b/tests/Documents/User.php @@ -34,6 +34,9 @@ class User extends BaseDocument #[ODM\Field(type: 'date')] protected $createdAt; + #[ODM\Field(type: 'date', nullable: true, name: 'disable-at')] + protected ?DateTimeInterface $disabledAt; + /** @var Address|null */ #[ODM\EmbedOne(targetDocument: Address::class)] protected $address; @@ -211,6 +214,11 @@ public function getCreatedAt() return $this->createdAt; } + public function getDisabledAt(): ?DateTimeInterface + { + return $this->disabledAt; + } + public function getAddress(): ?Address { return $this->address;