Doctrine MongoDB ODM
  1. Doctrine MongoDB ODM
  2. MODM-116

Collection Per Class Inheritance : Documents of a child class referenced in a parent class may be saved to the parent collection

    Details

    • Type: Bug Bug
    • Status: Reopened
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 1.0.0BETA3
    • Fix Version/s: None
    • Component/s: Document Manager
    • Labels:
      None

      Description

      Here is my class hierarchy (classes & attributes renamed for a better understanding) :

       
      /** @Document @InheritanceType("COLLECTION_PER_CLASS") **/
      class Parent {
          /** @ReferenceOne(targetDocument="Child") **/
          protected $child;
      }
      
      /** @Document **/
      class Child extends Parent {
      }
      

      When doing :

      $parent->setXXX($value);
      $parent->getChild()->setXXX($value2)
      

      the $parent->getChild() document is saved to the Parent collection.

      It looks like the problems lies in UnitOfWork::executeUpdates :

       
      if (get_class($document) == $className || $document instanceof Proxy && $document instanceof $className) {
      

      $child_document is an instance of Proxy (ChildProxy) and also an instance of Parent => saved using the Parent persister.

      Shouldn't the test be : get_class($document) == $className || get_class($document) == $className_of_Proxy ?

      As a side note : why "if ($class->isEmbeddedDocument)

      { continue; }

      " is within the foreach and not a "if ($class->isEmbeddedDocument)

      { return; }

      " at the beginning of the method ?

        Activity

        JF Bustarret created issue -
        Hide
        Jonathan H. Wage added a comment -

        I added a test for this here and it appears to be passing: https://github.com/doctrine/mongodb-odm/commit/3f24d77cc04adc0bb5532333e33826100457c666

        Show
        Jonathan H. Wage added a comment - I added a test for this here and it appears to be passing: https://github.com/doctrine/mongodb-odm/commit/3f24d77cc04adc0bb5532333e33826100457c666
        Jonathan H. Wage made changes -
        Field Original Value New Value
        Status Open [ 1 ] Closed [ 6 ]
        Fix Version/s 1.0.0BETA2 [ 10092 ]
        Resolution Cannot Reproduce [ 5 ]
        Hide
        JF Bustarret added a comment -

        I'll try to get more info on the problem and provide a test for it.

        Show
        JF Bustarret added a comment - I'll try to get more info on the problem and provide a test for it.
        Hide
        JF Bustarret added a comment -

        Here is a new test case :

         
        /** @Document
         *  @InheritanceType("COLLECTION_PER_CLASS")
         **/
        class MODM116Parent
        {
            /** @Id */
            private $id;
        
            /** @String */
            private $name;
        
            /** @ReferenceOne **/
            private $child;
        
            public function getId()
            {
                return $this->id;
            }
        
            public function getName()
            {
                return $this->name;
            }
        
            public function setName($name)
            {
                $this->name = $name;
            }
        
            public function getChild()
            {
                return $this->child;
            }
        
            public function setChild(MODM116Child $child)
            {
                $this->child = $child;
            }
        }
        
        /** @Document **/
        class MODM116Child extends MODM116Parent
        {
            
            /** @EmbedMany(targetDocument="MODM116Embedded") **/
            protected $embedded;
            
            function addEmbedded($parent) {
                $this->embedded[] = new MODM116Embedded($parent);
            }
        }
        
        /** @EmbeddedDocument **/
        class MODM116Embedded {
            
            /** @ReferenceOne(targetDocument="MODM116Parent") **/
            protected $parent;
            
            public function __construct($parent) {
                $this->parent = $parent;
            }
            
        }
        
        
        $parent = new MODM116Parent();
        $parent->setName('test');
        $parent->setChild(new MODM116Child());
        $dm->persist($parent->getChild());
        $dm->persist($parent);
        $dm->flush();
        $dm->clear();
        
        $parent = $dm->getRepository(get_class($parent))->findOneBy(array('name' => 'test'));
        
        $parent->getChild()->setName('ok');
        $parent->getChild()->addEmbedded($parent);
        $dm->flush();
        
        Show
        JF Bustarret added a comment - Here is a new test case : /** @Document * @InheritanceType("COLLECTION_PER_CLASS") **/ class MODM116Parent { /** @Id */ private $id; /** @String */ private $name; /** @ReferenceOne **/ private $child; public function getId() { return $this->id; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function getChild() { return $this->child; } public function setChild(MODM116Child $child) { $this->child = $child; } } /** @Document **/ class MODM116Child extends MODM116Parent { /** @EmbedMany(targetDocument="MODM116Embedded") **/ protected $embedded; function addEmbedded($parent) { $this->embedded[] = new MODM116Embedded($parent); } } /** @EmbeddedDocument **/ class MODM116Embedded { /** @ReferenceOne(targetDocument="MODM116Parent") **/ protected $parent; public function __construct($parent) { $this->parent = $parent; } } $parent = new MODM116Parent(); $parent->setName('test'); $parent->setChild(new MODM116Child()); $dm->persist($parent->getChild()); $dm->persist($parent); $dm->flush(); $dm->clear(); $parent = $dm->getRepository(get_class($parent))->findOneBy(array('name' => 'test')); $parent->getChild()->setName('ok'); $parent->getChild()->addEmbedded($parent); $dm->flush();
        JF Bustarret made changes -
        Resolution Cannot Reproduce [ 5 ]
        Status Closed [ 6 ] Reopened [ 4 ]
        Hide
        JF Bustarret added a comment -

        Pulled the last version from git. The bug still exists.

        Show
        JF Bustarret added a comment - Pulled the last version from git. The bug still exists.
        JF Bustarret made changes -
        Affects Version/s 1.0.0BETA3 [ 10124 ]
        Affects Version/s 1.0.0BETA2 [ 10092 ]
        Description
        Here is my class hierarchy (classes & attributes renamed for a better understanding) :

        {noformat}
        /** @Document @InheritanceType("COLLECTION_PER_CLASS") **/
        class Parent {
            /** @ReferenceOne(targetDocument="Child") **/
            protected $child;
        }

        /** @Document **/
        class Child extends Parent {
        }
        {noformat}

        When doing :
        {noformat}
        $parent->setXXX($value);
        $parent->getChild()->setXXX($value2)
        {noformat}

        the $parent->getChild() document is saved to the Parent collection.

        It looks like the problems lies in UnitOfWork::executeUpdates :

        {noformat}
        if (get_class($document) == $className || $document instanceof Proxy && $document instanceof $className) {
        {noformat}

        $child_document is an instance of Proxy (ChildProxy) and also an instance of Parent => saved using the Parent persister.

        Shouldn't the test be : get_class($document) == $className || get_class($document) == $className_of_Proxy ?

        As a side note : why "if ($class->isEmbeddedDocument) { continue; }" is within the foreach and not a "if ($class->isEmbeddedDocument) { return; }" at the beginning of the method ?
        Here is my class hierarchy (classes & attributes renamed for a better understanding) :

        {noformat}
        /** @Document @InheritanceType("COLLECTION_PER_CLASS") **/
        class Parent {
            /** @ReferenceOne(targetDocument="Child") **/
            protected $child;
        }

        /** @Document **/
        class Child extends Parent {
        }
        {noformat}

        When doing :
        {noformat}
        $parent->setXXX($value);
        $parent->getChild()->setXXX($value2)
        {noformat}

        the $parent->getChild() document is saved to the Parent collection.

        It looks like the problems lies in UnitOfWork::executeUpdates :

        {noformat}
        if (get_class($document) == $className || $document instanceof Proxy && $document instanceof $className) {
        {noformat}

        $child_document is an instance of Proxy (ChildProxy) and also an instance of Parent => saved using the Parent persister.

        Shouldn't the test be : get_class($document) == $className || get_class($document) == $className_of_Proxy ?

        As a side note : why "if ($class->isEmbeddedDocument) { continue; }" is within the foreach and not a "if ($class->isEmbeddedDocument) { return; }" at the beginning of the method ?
        Hide
        JF Bustarret added a comment -

        Up. Any news on a fix ?

        Show
        JF Bustarret added a comment - Up. Any news on a fix ?

        This list may be incomplete, as errors occurred whilst retrieving source from linked applications:

        • Request to http://www.doctrine-project.org/fisheye/ failed: Error in remote call to 'FishEye 0 (http://www.doctrine-project.org/fisheye/)' (http://www.doctrine-project.org/fisheye) [AbstractRestCommand{path='/rest-service-fe/search-v1/crossRepositoryQuery', params={query=MODM-116, expand=changesets[0:20].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

          People

          • Assignee:
            Jonathan H. Wage
            Reporter:
            JF Bustarret
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: