Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-568

Notice 'Undefined index' in UnitOfWork when hydrating partial objects with OneToOne assoc (owning side)

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.0-BETA1
    • Fix Version/s: 2.0-BETA2
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      There's an object with OneToOne association (the owning side).
      When trying to hydrate it using partial query NOTICE is outputted.

      Notice: undefined index [_FK column_name of OneToOne assoc_] in UnitOfWork on line: 1773

      Probably, the reason is in the way Query calls hydrator's iterate method (with no hints passed to it). Therefore the UnitOfWork object is not affected by HINT_FORCE_PARTIAL_LOAD hint set to the query object.

      Suggested solution:
      pass _hints array to a hydrator::iterate method when calling it from an AbstractQuery::iterate method.

      public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT)
          {
              return $this->_em->newHydrator($this->_hydrationMode)->iterate(
                  $this->_doExecute($params, $hydrationMode), $this->_resultSetMapping, /* HERE IT IS ----> */ $this->_hints /* <-------- */
              );
          }
      

      Am I right?

        Activity

        Hide
        Roman S. Borschel added a comment -

        Can we see the code you're using? We need to create a testcase first before fixing it.

        The code example in the documentation is no longer correct. I updated it already but the docs did not regenerate yet.

        For partial objects, you need to use "select partial u.

        {id,name}

        from User u".

        The HINT_FORCE_PARTIAL_LOAD now actually means "no proxies" or "optimize everything possible". It really needs to be renamed

        Show
        Roman S. Borschel added a comment - Can we see the code you're using? We need to create a testcase first before fixing it. The code example in the documentation is no longer correct. I updated it already but the docs did not regenerate yet. For partial objects, you need to use "select partial u. {id,name} from User u". The HINT_FORCE_PARTIAL_LOAD now actually means "no proxies" or "optimize everything possible". It really needs to be renamed
        Show
        Roman S. Borschel added a comment - Documentation is now updated: http://www.doctrine-project.org/documentation/manual/2_0/en/configuration:partial-objects
        Hide
        Ivan Voskoboynyk added a comment - - edited

        > "select partial u.

        {id,name}

        from User u"
        Use of PARTIAL keyword is possible for DQL queries. How it could be done using native sql queries?

        Here is a reproducible test case using sandbox data model:

         
        $userA = new \Entities\User();
        $userA->setName("user A");
        $userA->setTest("test A");
        $em->persist($userA);
        
        $em->flush();
        $em->clear();
        
        
        $sql = "SELECT u.id, u.name, u.test FROM users u";
        $rsMapping = new \Doctrine\ORM\Query\ResultSetMapping();
        $rsMapping->addEntityResult("Entities\User", "u");
        $rsMapping->addFieldResult("u", "id", "id");
        $rsMapping->addFieldResult("u", "name", "name");
        $rsMapping->addFieldResult("u", "test", "test");
        
        $query = $em->createNativeQuery($sql, $rsMapping);
        
        // Without fix in AbstractQuery::iterate() described above this is of no use
        $query->setHint(\Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD, true);
        
        $iterableResult = $query->iterate();
        foreach ($iterableResult as $row) {
            $user = $row[0];
            echo "<pre>";
            \Doctrine\Common\Util\Debug::dump($user);
            echo "</pre>";
            $em->remove($user);
        }
        
        $em->flush();
        

        Listed code outputs this:

        Notice: Undefined index: address_id in ***\Doctrine\ORM\UnitOfWork.php on line 1773
        
        object(stdClass)#66 (5) {
          ["__CLASS__"]=>
          string(13) "Entities\User"
          ["id"]=>
          int(29)
          ["name"]=>
          string(6) "user A"
          ["test"]=>
          string(6) "test A"
          ["address"]=>
          NULL
        }
        
        Show
        Ivan Voskoboynyk added a comment - - edited > "select partial u. {id,name} from User u" Use of PARTIAL keyword is possible for DQL queries. How it could be done using native sql queries? Here is a reproducible test case using sandbox data model: $userA = new \Entities\User(); $userA->setName( "user A" ); $userA->setTest( "test A" ); $em->persist($userA); $em->flush(); $em->clear(); $sql = "SELECT u.id, u.name, u.test FROM users u" ; $rsMapping = new \Doctrine\ORM\Query\ResultSetMapping(); $rsMapping->addEntityResult( "Entities\User" , "u" ); $rsMapping->addFieldResult( "u" , "id" , "id" ); $rsMapping->addFieldResult( "u" , "name" , "name" ); $rsMapping->addFieldResult( "u" , "test" , "test" ); $query = $em->createNativeQuery($sql, $rsMapping); // Without fix in AbstractQuery::iterate() described above this is of no use $query->setHint(\Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD, true ); $iterableResult = $query->iterate(); foreach ($iterableResult as $row) { $user = $row[0]; echo "<pre>" ; \Doctrine\Common\Util\Debug::dump($user); echo "</pre>" ; $em->remove($user); } $em->flush(); Listed code outputs this: Notice: Undefined index: address_id in ***\Doctrine\ORM\UnitOfWork.php on line 1773 object(stdClass)#66 (5) { [ "__CLASS__" ]=> string(13) "Entities\User" [ "id" ]=> int (29) [ "name" ]=> string(6) "user A" [ "test" ]=> string(6) "test A" [ "address" ]=> NULL }
        Hide
        Ivan Voskoboynyk added a comment -

        Improved formatting and code highlighting.

        Show
        Ivan Voskoboynyk added a comment - Improved formatting and code highlighting.
        Hide
        Benjamin Eberlei added a comment -

        Fixed

        Show
        Benjamin Eberlei added a comment - Fixed

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Ivan Voskoboynyk
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: