diff --git a/lib/Doctrine/ODM/MongoDB/Hydrator.php b/lib/Doctrine/ODM/MongoDB/Hydrator.php index d25208cda0..519de868c8 100644 --- a/lib/Doctrine/ODM/MongoDB/Hydrator.php +++ b/lib/Doctrine/ODM/MongoDB/Hydrator.php @@ -124,6 +124,14 @@ public function hydrate($document, &$data) $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument); $embeddedMetadata = $this->dm->getClassMetadata($className); $value = $embeddedMetadata->newInstance(); + + // unset a potential discriminator map field (unless it's a persisted property) + $discriminatorField = isset($mapping['discriminatorField']) ? $mapping['discriminatorField'] : '_doctrine_class_name'; + if (!isset($embeddedMetadata->fieldMappings[$discriminatorField])) + { + unset($embeddedDocument[$discriminatorField]); + } + $this->hydrate($value, $embeddedDocument); $data[$mapping['name']] = $embeddedDocument; $this->dm->getUnitOfWork()->registerManaged($value, null, $embeddedDocument); @@ -134,6 +142,14 @@ public function hydrate($document, &$data) $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument); $embeddedMetadata = $this->dm->getClassMetadata($className); $embeddedDocumentObject = $embeddedMetadata->newInstance(); + + // unset a potential discriminator map field (unless it's a persisted property) + $discriminatorField = isset($mapping['discriminatorField']) ? $mapping['discriminatorField'] : '_doctrine_class_name'; + if (!isset($embeddedMetadata->fieldMappings[$discriminatorField])) + { + unset($embeddedDocument[$discriminatorField]); + } + $this->hydrate($embeddedDocumentObject, $embeddedDocument); $data[$mapping['name']][$key] = $embeddedDocument; $this->dm->getUnitOfWork()->registerManaged($embeddedDocumentObject, null, $embeddedDocument); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM90Test.php b/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM90Test.php new file mode 100644 index 0000000000..b0de5f017b --- /dev/null +++ b/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM90Test.php @@ -0,0 +1,116 @@ +listener = new MODM90EventListener(); + $evm = $this->dm->getEventManager(); + $events = array( + ODMEvents::preUpdate, + ODMEvents::postUpdate, + ); + $evm->addEventListener($events, $this->listener); + return $this->dm; + } + + public function testDocumentWithEmbeddedDocumentNotUpdatedOnFlush() + { + $dm = $this->getDocumentManager(); + + $testDoc = new MODM90TestDocument(); + $testDoc->name = 'Parent'; + $testDoc->embedded = new MODM90TestEmbeddedDocument(); + $testDoc->embedded->name = 'Child'; + $dm->persist($testDoc); + $dm->flush(); + $dm->clear(); + + $testDoc = $dm->findOne(__NAMESPACE__.'\MODM90TestDocument'); + + // run a flush, in theory, nothing should be flushed. + $dm->flush(); + $dm->clear(); + + // no update events should be called + $called = array(); + $this->assertEquals($called, $this->listener->called); + } + + /* + * Ensures that the descriminator field is not unset if it's a + * real property on the document. + */ + public function testDiscriminatorFieldValuePresentIfRealProperty() + { + $dm = $this->getDocumentManager(); + + $testDoc = new MODM90TestDocument(); + $testDoc->name = 'Parent'; + $testDoc->embedded = new MODM90Test2EmbeddedDocument(); + $testDoc->embedded->name = 'Child'; + $dm->persist($testDoc); + $dm->flush(); + $dm->clear(); + + $testDoc = $dm->findOne(__NAMESPACE__.'\MODM90TestDocument'); + + $this->assertEquals($testDoc->embedded->type, 'test2'); + } +} + +class MODM90EventListener +{ + public $called = array(); + public function __call($method, $args) + { + $document = $args[0]->getDocument(); + $className = get_class($document); + $this->called[$method][] = $className; + } +} + +/** @Document */ +class MODM90TestDocument +{ + /** @Id */ + public $id; + + /** @String */ + public $name; + + /** + * @EmbedOne + * ( + * discriminatorField="type", + * discriminatorMap={ + * "test"="MODM90TestEmbeddedDocument", + * "test2"="MODM90Test2EmbeddedDocument" + * } + * ) + */ + public $embedded; +} + +/** @EmbeddedDocument */ +class MODM90TestEmbeddedDocument +{ + /** @String */ + public $name; +} + +/** @EmbeddedDocument */ +class MODM90Test2EmbeddedDocument +{ + /** @String */ + public $name; + + /** @String The discriminator field is a real property */ + public $type; +} \ No newline at end of file