Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-3170

SimpleObjectHydrator fails to get discriminator column from mapped SQL result

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All

      Description

      When querying a simple entity which uses single table- or class table inheritance using simple object hydration (AbstractQuery::HYDRATE_SIMPLEOBJECT), the mapped discriminator column is not retrieved correctly.

      Example:

      /**
       * @Entity
       * @InheritanceType("JOINED")
       * @DiscriminatorColumn(name="type", type="string")
       * @DiscriminatorMap({"product" = "Product"})
       */
      abstract class AbstractEntity
      {
          /** @Id @Column(type="integer") @GeneratedValue */
          public $id;
      }
      
      /**
       * @Entity
       */
      class Product extends AbstractEntity
      {
      }
      
      $manager->createQueryBuilder()
                      ->select('p')
                      ->from('Product, 'p')
                      ->getQuery()
                      ->getResult(AbstractQuery::HYDRATE_SIMPLEOBJECT);
      
      // -> Exception: [Doctrine\ORM\Internal\Hydration\HydrationException] The discriminator column "type" is missing for "Product" using the DQL alias "p".
      

      The SQL statement used is equal to:

      SELECT r0_.id AS id0, r0_.type AS type1 FROM Product r1_ INNER JOIN AbstractEntity r0_ ON r1_.id = r0_.id
      

      As you can see, the type column is given an alias of type1. This is saved in the ResultSetMapping of the request but not taken into account when actually retrieving the discriminator column back from the SQL result.

      The problem is inside SimpleObjectHydrator#hydrateRowData().

      When the discriminator column name is fetched via

      $discrColumnName = $this->_platform->getSQLResultCasing($this->class->discriminatorColumn['name']);
      

      the result is simply type which is wrong because the alias is type2. This can be fixed by adding

      if ($metaMappingDiscrColumnName = array_search($discrColumnName, $this->_rsm->metaMappings)) {
          $discrColumnName = $metaMappingDiscrColumnName;
      }
      

      right after the column retrieval, because then the alias of the meta field type is correctly taken into account.

      I'll create a PR with a unit test for this fix right after this ticket's creation.

      I hope I'm doing everything right, this is my first contribution.

        Activity

        Hide
        Ulf Reimers added a comment -

        PR is https://github.com/doctrine/doctrine2/pull/1060

        I though that I first create a ticket, then propose a fix for that with a PR and by adding the Ticket ID in the PR-Title they are linked automatically. But unfortunately it seems I've done something wrong there.

        Show
        Ulf Reimers added a comment - PR is https://github.com/doctrine/doctrine2/pull/1060 I though that I first create a ticket, then propose a fix for that with a PR and by adding the Ticket ID in the PR-Title they are linked automatically. But unfortunately it seems I've done something wrong there.
        Hide
        Doctrine Bot added a comment -

        A related Github Pull-Request [GH-1060] was closed:
        https://github.com/doctrine/doctrine2/pull/1060

        Show
        Doctrine Bot added a comment - A related Github Pull-Request [GH-1060] was closed: https://github.com/doctrine/doctrine2/pull/1060

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Ulf Reimers
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: