From 0a0764359508475563fac661267a20162baed1d6 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Thu, 18 Jun 2015 10:14:01 +0200 Subject: [PATCH 1/2] Store parent association before hydrating document --- lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php | 3 ++- lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php b/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php index 99b297c7c2..d6b13a0b2c 100644 --- a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php +++ b/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php @@ -338,11 +338,12 @@ private function generateHydratorClass(ClassMetadata $class, $hydratorClassName, \$embeddedMetadata = \$this->dm->getClassMetadata(\$className); \$return = \$embeddedMetadata->newInstance(); + \$this->unitOfWork->setParentAssociation(\$return, \$this->class->fieldMappings['%2\$s'], \$document, '%1\$s'); + \$embeddedData = \$this->dm->getHydratorFactory()->hydrate(\$return, \$embeddedDocument, \$hints); \$embeddedId = \$embeddedMetadata->identifier && isset(\$embeddedData[\$embeddedMetadata->identifier]) ? \$embeddedData[\$embeddedMetadata->identifier] : null; \$this->unitOfWork->registerManaged(\$return, \$embeddedId, \$embeddedData); - \$this->unitOfWork->setParentAssociation(\$return, \$this->class->fieldMappings['%2\$s'], \$document, '%1\$s'); \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; diff --git a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php b/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php index 0d45a5de1e..12ba8201b1 100644 --- a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php +++ b/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php @@ -646,13 +646,14 @@ private function loadEmbedManyCollection(PersistentCollection $collection) $embeddedMetadata = $this->dm->getClassMetadata($className); $embeddedDocumentObject = $embeddedMetadata->newInstance(); + $this->uow->setParentAssociation($embeddedDocumentObject, $mapping, $owner, $mapping['name'] . '.' . $key); + $data = $this->hydratorFactory->hydrate($embeddedDocumentObject, $embeddedDocument); $id = $embeddedMetadata->identifier && isset($data[$embeddedMetadata->identifier]) ? $data[$embeddedMetadata->identifier] : null; $this->uow->registerManaged($embeddedDocumentObject, $id, $data); - $this->uow->setParentAssociation($embeddedDocumentObject, $mapping, $owner, $mapping['name'] . '.' . $key); if ($mapping['strategy'] === 'set' || $mapping['strategy'] === 'atomicSet') { $collection->set($key, $embeddedDocumentObject); } else { From 10663b8e2e5a55ea51d9a9b2af8b5131ed59170a Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Thu, 18 Jun 2015 17:42:17 +0200 Subject: [PATCH 2/2] Add test to check if parentAssociation is available in postLoad --- .../Tests/Functional/Ticket/GH1152Test.php | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1152Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1152Test.php b/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1152Test.php new file mode 100644 index 0000000000..74411940fe --- /dev/null +++ b/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1152Test.php @@ -0,0 +1,65 @@ +dm->getEventManager()->addEventListener(Events::postLoad, $listener); + + $parent = new GH1152Parent(); + $parent->child = new GH1152Child(); + + $this->dm->persist($parent); + $this->dm->flush(); + + $this->dm->clear(); + + $parent = $this->dm->find(GH1152Parent::CLASSNAME, $parent->id); + $this->assertNotNull($parent); + + $this->assertNotNull($parent->child->parentAssociation); + list($mapping, $parentAssociation, $fieldName) = $parent->child->parentAssociation; + + $this->assertSame($parent, $parentAssociation); + } +} + +/** @ODM\Document */ +class GH1152Parent +{ + const CLASSNAME = __CLASS__; + + /** @ODM\Id */ + public $id; + + /** @ODM\EmbedOne(targetDocument="GH1152Child") */ + public $child; +} + +/** @ODM\EmbeddedDocument */ +class GH1152Child +{ + public $parentAssociation; +} + +class GH1152Listener +{ + public function postLoad(LifecycleEventArgs $args) + { + $dm = $args->getDocumentManager(); + $document = $args->getDocument(); + + if (!$document instanceof GH1152Child) { + return; + } + + $document->parentAssociation = $dm->getUnitOfWork()->getParentAssociation($document); + } +}