Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.3.4
    • Fix Version/s: 2.5
    • Component/s: ORM
    • Security Level: All
    • Labels:

      Description

      I have the following class mappings:

      class A
      {
          /**
           * @Id
           * @Column(type="integer")
           * @GeneratedValue(strategy="AUTO")
           */
          protected $id;
          
          /**
           * @Column(type="string", length=100, nullable=FALSE)
           */    
          protected $sampleField;
          
          /**
           * @OneToOne(targetEntity="B", mappedBy="aRelation")
           **/     
          protected $bRelation;
      }
      
      class B
      {
          /**
           * @Id
           * @OneToOne(targetEntity="A", inversedBy="bRelation")
           * @JoinColumn(name="a_id", referencedColumnName="id", nullable=FALSE, onDelete="CASCADE")
           */
          protected $aRelation;
      
          /**
           * @ManyToOne(targetEntity="C")
           * @JoinColumn(name="c_id", referencedColumnName="id", nullable=FALSE, onDelete="CASCADE")
           */
          protected $cRelation;
      
      }
      
      class C
      {
          /**
           * @Id
           * @Column(type="integer")
           * @GeneratedValue(strategy="AUTO")
           */
          protected $id;
          
          /**
           * @Column(type="string", length=100, nullable=FALSE)
           */    
          protected $sampleField;
      }
      

      Then I make the following query:

      $qb = $em->createQueryBuilder();
      $qb = $qb->select('a, b, c')
            ->from('A','a')
            ->leftJoin('a.bRelation', 'b')
            ->leftJoin('b.cRelation', 'c');
            
      $result = $qb->getQuery()->getResult();
      

      The result contains a collection of instances of class A with the a.bRelation field populated and the a.bRelation.cRelation field populated in all rows except the last one.

      The problem is an hydration problem. The Parser constructs the select statement with the fields of class A, then the fields of class C and last the fields of class B. The hydrator don't work correctly because when it's hydrating class C it doesn't find the class B (because it appears last in the select statement).
      I think the problem is because class B only contains associations. If i put an extra field (an string for example) in class B it works as expected.

        Activity

        Hide
        Karol Horowski added a comment -

        After Popy's suggestion I added $this->_em->clear() and now I have failing test. My fault with this quick "everything is ok".

        I tried to search what's happening in ObjectHydrator but something strange is going on in hydrateRowData method.

        Show
        Karol Horowski added a comment - After Popy's suggestion I added $this->_em->clear() and now I have failing test. My fault with this quick "everything is ok". I tried to search what's happening in ObjectHydrator but something strange is going on in hydrateRowData method.
        Hide
        Popy added a comment -

        Be carefull, headache come fast while reading this method

        As far as I know, the problem could be solved if the hydrator started by hydrating the root entity first. Maybe.

        Show
        Popy added a comment - Be carefull, headache come fast while reading this method As far as I know, the problem could be solved if the hydrator started by hydrating the root entity first. Maybe.
        Hide
        Karol Horowski added a comment -

        In select statement fields are in this order Root, B, A. Relations in my test are Root 1:1 A *:1 B.
        Hydrator first gets Root data and next B. But here (line 407 in ObjectHydrator) it doesn't find A parent in resultPointers.

        For now I don't have any idea how to add new logic for this.

        Show
        Karol Horowski added a comment - In select statement fields are in this order Root, B, A. Relations in my test are Root 1:1 A *:1 B. Hydrator first gets Root data and next B. But here (line 407 in ObjectHydrator) it doesn't find A parent in resultPointers. For now I don't have any idea how to add new logic for this.
        Hide
        Doctrine Bot added a comment -

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

        Show
        Doctrine Bot added a comment - A related Github Pull-Request [GH-878] was closed: https://github.com/doctrine/doctrine2/pull/878
        Show
        Guilherme Blanco added a comment - As of https://github.com/doctrine/doctrine2/commit/38b683838648b549aad0e38ce88c70b6393755b3 this issue is now fixed.

          People

          • Assignee:
            Guilherme Blanco
            Reporter:
            Nicolas Bottarini
          • Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: