Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1776

Abstract class marked as @Entity in a single table inheritance is wrongly hydrated

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Duplicate
    • Affects Version/s: 2.2.2
    • Fix Version/s: None
    • Component/s: ORM
    • Labels:
      None
    • Environment:
      Irrelevant

      Description

      I have the following entity hierarchy:

      /**
       * @Entity
       * @InheritanceType("SINGLE_TABLE")
       * @DiscriminatorColumn(name="type", type="string")
       * @DiscriminatorMap({
           "prospectEdited" = "Application\Domain\Model\Event\ProspectEditedEvent"
         })
       */
      abstract class Event {
      	// ...
      }
      
      /**
       * @Entity
       */
      abstract class ProspectEvent extends Event {
          /**
           * @ManyToOne(targetEntity="Application\Domain\Model\Prospect")
           */
          protected $prospect;
      }
      
      /**
       * @Entity
       */
      class ProspectEditedEvent extends ProspectEvent {
      	// ...
      }
      

      Although ProspectEvent is an abstract class, I need to mark it as @Entity, so that I can query for any type of ProspectEvent:

      SELECT e FROM ProspectEvent e WHERE e.prospect = ?
      

      So far, so good.
      The problem happens when I query the root class:

      SELECT e FROM Event e
      

      The query works fine, but the returned ProspectEvent entities have a NULL $prospect property.
      I noticed that in that case, the DocBlock for $prospect is totally ignored (a wrong @JoinColumn name for example, doesn't throw an exception).

      The workaround to make it work, is to add a "fake" entry to the discriminator map for the abstract class:

      @DiscriminatorMap({
        "prospectEvent"  = "Application\Domain\Model\Event\ProspectEvent"
        "prospectEdited" = "Application\Domain\Model\Event\ProspectEditedEvent"
      })
      

      Even though there is no such "prospectEvent" discriminator entry possible, as the class is abstract.
      Final point, if I remove the @Entity DocBlock on ProspectEvent, $prospect is hydrated correctly, but then it is not possible to issue a DQL query on ProspectEvent anymore.

        Activity

        Benjamin Morel created issue -
        Benjamin Morel made changes -
        Field Original Value New Value
        Description I have the following entity hierarchy:

        {code}
        /**
         * @Entity
         * @InheritanceType("SINGLE_TABLE")
         * @DiscriminatorColumn(name="type", type="string")
         * @DiscriminatorMap({
             "prospectEdited" = "Application\Domain\Model\Event\ProspectEditedEvent"
           })
         */
        abstract class Event {
        // ...
        }

        /**
         * @Entity
         */
        abstract class ProspectEvent extends Event {
            /**
             * @ManyToOne(targetEntity="Application\Domain\Model\Prospect")
             */
            protected $prospect;
        }

        /**
         * @Entity
         */
        class ProspectEditedEvent extends ProspectEvent {
        // ...
        }
        {code}

        Although ProspectEvent is an abstract class, I need to mark it as @Entity, so that I can query for any type of ProspectEvent:
        {code}
        SELECT e FROM ProspectEvent e WHERE e.prospect = ?
        {code}

        So far, so good.
        The problem happens when I query the root class:
        {code}
        SELECT e FROM Event e
        {code}

        The query works fine, but the returned ProspectEvent entities have a NULL $prospect property.
        I noticed that in that case, the DocBlock for $prospect is totally ignored (a wrong column name doesn't throw an exception).

        The workaround to make it work, is to add a "fake" entry to the discriminator map for the abstract class:
        {code}
        @DiscriminatorMap({
          "prospectEvent" = "Application\Domain\Model\Event\ProspectEvent"
          "prospectEdited" = "Application\Domain\Model\Event\ProspectEditedEvent"
        })
        {code}

        Even though there is no such "prospectEvent" discriminator entry possible, as the class is abstract.
        Final point, if I remove the @Entity DocBlock on ProspectEvent, $prospect is hydrated correctly, but then it is not possible to issue a DQL query on ProspectEvent anymore.
        I have the following entity hierarchy:

        {code}
        /**
         * @Entity
         * @InheritanceType("SINGLE_TABLE")
         * @DiscriminatorColumn(name="type", type="string")
         * @DiscriminatorMap({
             "prospectEdited" = "Application\Domain\Model\Event\ProspectEditedEvent"
           })
         */
        abstract class Event {
        // ...
        }

        /**
         * @Entity
         */
        abstract class ProspectEvent extends Event {
            /**
             * @ManyToOne(targetEntity="Application\Domain\Model\Prospect")
             */
            protected $prospect;
        }

        /**
         * @Entity
         */
        class ProspectEditedEvent extends ProspectEvent {
        // ...
        }
        {code}

        Although ProspectEvent is an abstract class, I need to mark it as @Entity, so that I can query for any type of ProspectEvent:
        {code}
        SELECT e FROM ProspectEvent e WHERE e.prospect = ?
        {code}

        So far, so good.
        The problem happens when I query the root class:
        {code}
        SELECT e FROM Event e
        {code}

        The query works fine, but the returned ProspectEvent entities have a NULL $prospect property.
        I noticed that in that case, the DocBlock for $prospect is totally ignored (a wrong @JoinColumn name for example, doesn't throw an exception).

        The workaround to make it work, is to add a "fake" entry to the discriminator map for the abstract class:
        {code}
        @DiscriminatorMap({
          "prospectEvent" = "Application\Domain\Model\Event\ProspectEvent"
          "prospectEdited" = "Application\Domain\Model\Event\ProspectEditedEvent"
        })
        {code}

        Even though there is no such "prospectEvent" discriminator entry possible, as the class is abstract.
        Final point, if I remove the @Entity DocBlock on ProspectEvent, $prospect is hydrated correctly, but then it is not possible to issue a DQL query on ProspectEvent anymore.
        Benjamin Eberlei made changes -
        Workflow jira [ 13630 ] jira-feedback [ 14049 ]
        Benjamin Eberlei made changes -
        Workflow jira-feedback [ 14049 ] jira-feedback2 [ 15913 ]
        Benjamin Eberlei made changes -
        Workflow jira-feedback2 [ 15913 ] jira-feedback3 [ 18168 ]
        Marco Pivetta made changes -
        Assignee Benjamin Eberlei [ beberlei ] Marco Pivetta [ ocramius ]
        Security All [ 10000 ]
        Benjamin Eberlei made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Benjamin Eberlei made changes -
        Resolution Fixed [ 1 ]
        Status Resolved [ 5 ] Reopened [ 4 ]
        Benjamin Eberlei made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Duplicate [ 3 ]

          People

          • Assignee:
            Marco Pivetta
            Reporter:
            Benjamin Morel
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: