Uploaded image for project: 'Doctrine MongoDB ODM'
  1. Doctrine MongoDB ODM
  2. MODM-123

Single Collection Inheritance : hydration won't work properly

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Blocker
    • Resolution: Fixed
    • Affects Version/s: 1.0.0BETA2
    • Fix Version/s: 1.0.0BETA2
    • Component/s: None
    • Labels:
      None
    • Environment:
      Mac OS X, MAMP

      Description

      There is still a problem with Single Collection Inheritance.

      Please consider the following code :

       
      /**
       * @Document(db="forum", collection="Items")
       * @InheritanceType("SINGLE_COLLECTION")
       * @DiscriminatorField(fieldName="type")
       * @DiscriminatorMap({0="Items", 1="Stuffs"})
      */
      class Items
      {
          /**
           *
           * @id
           */
          public $id;
      
          /**
           * @String
           */
          public $title;
      }
      
      
      
      /**
       * @Document(db="forum", collection="Items")
      */
      class Stuffs extends Items
      {
          
          /**
           *
           * @id
           */
          public $id;
      
          /**
           * @String
           */
          public $stuffname;
      
      }
      
      $a = new Stuffs();
      $a->stuffname = 'TTT';
      $dm->persist($a);
      $dm->flush();
      

      Resulting in the database with :

       
      {
         "_id": ObjectId("4d5dd082b53251b84e000000"),
         "stuffname": "TTT",
         "type": 1 
      }
      

      Now if I do :

       
      $result = $dm->find('Items', $a->id);
      

      then $result is an instance of Stuffs

      But if I try :

       
      $result = $dm->find('Items', '4d5dd082b53251b84e000000'); 
      

      then $result is an instance of Items

      Note that '$a->id' is a string, the same string containing '4d5dd082b53251b84e000000', so :

       
      $result = $dm->find('Items', $a->id); 
      $result = $dm->find('Items', '4d5dd082b53251b84e000000'); 
      

      are semantically equivalent. It seems however that hydration would ignore the DiscriminatorMap in the second example.

      However If you do :

       
      $result = $dm->find('Stuffs', '4d5dd082b53251b84e000000'); 
      

      You'll get a Stuffs as a result.

      Now I tried to find a workaround when you don't know the type of the returned object. My initial intention was to first fetch a document with :

       
      $result = $dm->find('Items', '4d5dd082b53251b84e000000'); 
      

      Then I'm testing a property in the objet to see if it's a Stuffs, if it is, I tried an new :

       
      $result = $dm->find('Stuffs', '4d5dd082b53251b84e000000'); 
      

      In order to fetch a Stuffs. But ... I still get a *Items"!

      So basically, if you do :

       
      $result = $dm->find('Stuffs', '4d5dd082b53251b84e000000'); 
      

      You get a Stuffs. But if you do :

       
      $dm->find('Items', '4d5dd082b53251b84e000000'); 
      $result = $dm->find('Stuffs', '4d5dd082b53251b84e000000'); 
      

      You get a Items!

        Activity

        billybob Billy Bob created issue -
        billybob Billy Bob made changes -
        Field Original Value New Value
        Description There is still a problem with Single Collection Inheritance.

        Please consider the following code :
        {noformat}
        /**
         * @Document(db="forum", collection="Items")
         * @InheritanceType("SINGLE_COLLECTION")
         * @DiscriminatorField(fieldName="type")
         * @DiscriminatorMap({0="Items", 1="Stuffs"})
        */
        class Items
        {
            /**
             *
             * @id
             */
            public $id;

            /**
             * @String
             */
            public $title;
        }



        /**
         * @Document(db="forum", collection="Items")
        */
        class Stuffs extends Items
        {
            
            /**
             *
             * @id
             */
            public $id;

            /**
             * @String
             */
            public $stuffname;

        }

        $a = new Stuffs();
        $a->stuffname = 'TTT';
        $dm->persist($a);
        $dm->flush();
        {noformat}

        Resulting in the database with :
        {noformat}
        {
           "_id": ObjectId("4d5dd082b53251b84e000000"),
           "stuffname": "TTT",
           "type": 1
        }
        {noformat}
        Now if I do :
        {noformat}
        $result = $dm->find('Items', $a->id);
        {noformat}
        then $result is an instance of *Stuffs*

        But if I try :
        {noformat}
        $result = $dm->find('Items', '4d5dd082b53251b84e000000');
        {noformat}
        then $result is an instance of *Items*

        Note that '$a->id' is a string, the same string containing '4d5dd082b53251b84e000000', so :
        {noformat}
        $result = $dm->find('Items', $a->id);
        $result = $dm->find('Items', '4d5dd082b53251b84e000000');
        {noformat}
        are semantically equivalent. It seems however that hydration would ignore the DiscriminatorMap in the second example.
        There is still a problem with Single Collection Inheritance.

        Please consider the following code :
        {noformat}
        /**
         * @Document(db="forum", collection="Items")
         * @InheritanceType("SINGLE_COLLECTION")
         * @DiscriminatorField(fieldName="type")
         * @DiscriminatorMap({0="Items", 1="Stuffs"})
        */
        class Items
        {
            /**
             *
             * @id
             */
            public $id;

            /**
             * @String
             */
            public $title;
        }



        /**
         * @Document(db="forum", collection="Items")
        */
        class Stuffs extends Items
        {
            
            /**
             *
             * @id
             */
            public $id;

            /**
             * @String
             */
            public $stuffname;

        }

        $a = new Stuffs();
        $a->stuffname = 'TTT';
        $dm->persist($a);
        $dm->flush();
        {noformat}

        Resulting in the database with :
        {noformat}
        {
           "_id": ObjectId("4d5dd082b53251b84e000000"),
           "stuffname": "TTT",
           "type": 1
        }
        {noformat}
        Now if I do :
        {noformat}
        $result = $dm->find('Items', $a->id);
        {noformat}
        then $result is an instance of *Stuffs*

        But if I try :
        {noformat}
        $result = $dm->find('Items', '4d5dd082b53251b84e000000');
        {noformat}
        then $result is an instance of *Items*

        Note that '$a->id' is a string, the same string containing '4d5dd082b53251b84e000000', so :
        {noformat}
        $result = $dm->find('Items', $a->id);
        $result = $dm->find('Items', '4d5dd082b53251b84e000000');
        {noformat}
        are semantically equivalent. It seems however that hydration would ignore the DiscriminatorMap in the second example.

        However If you do :
        {noformat}
        $result = $dm->find('Stuffs', '4d5dd082b53251b84e000000');
        {noformat}
        You'll get a *Stuffs* as a result.


        Now I tried to find a workaround when you don't know the type of the returned object. My initial intention was to first fetch a document with :
        {noformat}
        $result = $dm->find('Items', '4d5dd082b53251b84e000000');
        {noformat}
        Then I'm testing a property in the objet to see if it's a *Stuffs*, if it is, I tried an new :
        {noformat}
        $result = $dm->find('Stuffs', '4d5dd082b53251b84e000000');
        {noformat}
        In order to fetch a *Stuffs*. But ... I still get a *Items"!

        So basically, if you do :
        {noformat}
        $result = $dm->find('Stuffs', '4d5dd082b53251b84e000000');
        {noformat}
        You get a *Stuffs*. But if you do :
        {noformat}
        $dm->find('Items', '4d5dd082b53251b84e000000');
        $result = $dm->find('Stuffs', '4d5dd082b53251b84e000000');
        {noformat}
        You get a *Items*!
        Show
        jwage Jonathan H. Wage added a comment - Hi, can you make a phpunit testcase here? https://github.com/doctrine/mongodb-odm/tree/master/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket
        Hide
        billybob Billy Bob added a comment -

        Sorry but I'm not familiar with phpunit.

        If that can help, I've made more tests here. Strangely when I deleted all the documents in the test base and created new ones, the hydration then worken properly! However in my real project, the issue is still here ...

        In conclusion it seems that the issue is random.

        Show
        billybob Billy Bob added a comment - Sorry but I'm not familiar with phpunit. If that can help, I've made more tests here. Strangely when I deleted all the documents in the test base and created new ones, the hydration then worken properly! However in my real project, the issue is still here ... In conclusion it seems that the issue is random.
        Hide
        jwage Jonathan H. Wage added a comment -

        I am not able to produce the issue here. Can you make a executable test that I can run so that I can see what you see?

        Show
        jwage Jonathan H. Wage added a comment - I am not able to produce the issue here. Can you make a executable test that I can run so that I can see what you see?
        jwage Jonathan H. Wage made changes -
        Affects Version/s 1.0.0BETA2 [ 10092 ]
        Affects Version/s 1.0.0BETA1 [ 10080 ]
        Fix Version/s 1.0.0BETA3 [ 10124 ]
        Hide
        billybob Billy Bob added a comment -

        Doesn't seem to be an issue in BETA2.

        Show
        billybob Billy Bob added a comment - Doesn't seem to be an issue in BETA2.
        billybob Billy Bob made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Fix Version/s 1.0.0BETA2 [ 10092 ]
        Fix Version/s 1.0.0BETA3 [ 10124 ]
        Resolution Fixed [ 1 ]

        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={expand=changesets[0:20].revisions[0:29],reviews, query=MODM-123}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

          People

          • Assignee:
            jwage Jonathan H. Wage
            Reporter:
            billybob Billy Bob
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: