Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-827

Class Table Inheritance is broken when child classes have the same properties

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Invalid
    • Affects Version/s: 2.0-BETA4
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      I create one Superclass and several Subclasses. The subclasses have properties with the same name (but as I also want to have Subclasses without these properties, this is the only elegant construction), in this example "name".

      Now when I select the Superclass, I get all Subclass entities, but the "name" property is not hydrated correctly:

      <?php
      
      namespace Entities;
      
      /**
       * @Entity
       * @InheritanceType("JOINED")
       * @DiscriminatorColumn(name="type", type="integer")
       * @DiscriminatorMap({ "1" = "Subclass1", "2" = "Subclass2" })
       */
      class Superclass
      {
          /** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */
          public $id;
      }
      
      /** @Entity */
      class Subclass1 extends Superclass
      {
          /** @Column(type="string") */
          public $name;
      }
      
      /** @Entity */
      class Subclass2 extends Superclass
      {
          /** @Column(type="string") */
          public $name;
      }
      
      /* */
      
      $sub1 = new Subclass1;
      $sub1->name = 'sub1name';
      $em->persist($sub1);
      
      $sub2 = new Subclass2;
      $sub2->name = 'sub2name';
      $em->persist($sub2);
      
      $em->flush();
      $em->clear();
      
      $query = $em->createQuery('SELECT s FROM Entities\Superclass s');
      foreach ($query->execute() as $s) {
      	echo 'name = ' . $s->name . PHP_EOL;
      }
      

      Output:

      name = sub2name
      name = 
      

      The SQL however seems correct, both "name" columns are selected. This seems to be a bug in hydration.

        Activity

        Nico Kaiser created issue -
        Hide
        Benjamin Eberlei added a comment -

        Quoting from the Docs, chapter "Architecture" on the requirements of entities (and inheritance):

        Any two entity classes in a class hierarchy that inherit directly or indirectly from one another must not have a mapped property with the same name. That is, if B inherits from A then B must not have a mapped field with the same name as an already mapped field that is inherited from A.
        Show
        Benjamin Eberlei added a comment - Quoting from the Docs, chapter "Architecture" on the requirements of entities (and inheritance): Any two entity classes in a class hierarchy that inherit directly or indirectly from one another must not have a mapped property with the same name. That is, if B inherits from A then B must not have a mapped field with the same name as an already mapped field that is inherited from A.
        Benjamin Eberlei made changes -
        Field Original Value New Value
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Invalid [ 6 ]
        Hide
        Stan Imbt added a comment -

        Please reopen this issue. I can can confirm it and Benjamin's reason for rejecting it is invalid.

        The two classes in the example are in neither directly nor indirectly inheriting from one another. They just happen to be siblings, i. e. they have the same superclass.

        And to pre-empt the argument: It is not always bad design to have two classes in a hierarchy that have an identically named property. At least as long as PHP does not allow for horizontal re-use via traits or such.

        Take this scenario:

         
        SuperClass
        |
        +- SubClassA
        |  +- SubSubClass1
        |  +- SubSubClass2
        |
        +- SubClassB
           +- SubSubClass3
           +- SubSubClass4
        

        Now if the need arises to have a property 'foo' on both SubSubClass1 and SubSubClass4, and 'foo' shall not be part of the top-most super class, because it makes no sense in any of the other classes, then we unfortunately have to repeat ourselves or employ some bad magic which certainly cannot be mapped with Doctrine anyway.

        Show
        Stan Imbt added a comment - Please reopen this issue. I can can confirm it and Benjamin's reason for rejecting it is invalid. The two classes in the example are in neither directly nor indirectly inheriting from one another. They just happen to be siblings, i. e. they have the same superclass. And to pre-empt the argument: It is not always bad design to have two classes in a hierarchy that have an identically named property. At least as long as PHP does not allow for horizontal re-use via traits or such. Take this scenario: SuperClass | +- SubClassA | +- SubSubClass1 | +- SubSubClass2 | +- SubClassB +- SubSubClass3 +- SubSubClass4 Now if the need arises to have a property 'foo' on both SubSubClass1 and SubSubClass4, and 'foo' shall not be part of the top-most super class, because it makes no sense in any of the other classes, then we unfortunately have to repeat ourselves or employ some bad magic which certainly cannot be mapped with Doctrine anyway.
        Hide
        Benjamin Eberlei added a comment -

        There is another open issue that handles this issue. Its indeed a bug.

        Show
        Benjamin Eberlei added a comment - There is another open issue that handles this issue. Its indeed a bug.
        Benjamin Eberlei made changes -
        Workflow jira [ 11979 ] jira-feedback [ 14598 ]
        Benjamin Eberlei made changes -
        Workflow jira-feedback [ 14598 ] jira-feedback2 [ 16462 ]
        Benjamin Eberlei made changes -
        Workflow jira-feedback2 [ 16462 ] jira-feedback3 [ 18715 ]

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

          People

          • Assignee:
            Roman S. Borschel
            Reporter:
            Nico Kaiser
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: