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

Single Collection Inheritance : hydration won't work properly

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Blocker 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

        Billy Bob created issue -
        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
        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
        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
        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
        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
        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?
        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
        Billy Bob added a comment -

        Doesn't seem to be an issue in BETA2.

        Show
        Billy Bob added a comment - Doesn't seem to be an issue in BETA2.
        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={query=MODM-123, expand=changesets[0:20].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

          People

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

            Dates

            • Created:
              Updated:
              Resolved: