Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1010

Crash when fetching results from qb inside postLoad event

    Details

    • Type: Documentation Documentation
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.0.1
    • Fix Version/s: 2.4
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None
    • Environment:
      PHP 5.3.3-1ubuntu9.3
      KUbuntu 10.10

      Description

      I registered an event listener to my entity manager and on a postLoad event, I want to prepare some data in a nice way (fetch translations for my library + store into associative array into entity). Here's my snippet:

      class TranslationListener implements EventSubscriber
      {
          public function getSubscribedEvents()
          {
              return array(Events::postLoad);
          }
      
          public function postLoad(LifecycleEventArgs $args)
          {
              $em = $args->getEntityManager();
              $entity = $args->getEntity();
      
              if ($entity instanceof Lib) {
                  $qb = $em->createQueryBuilder();
                  $qb = $qb->select('T')->from('Translate', 'T')->join('T.locale', 'TT')->where('T.lib = ?1')->setParameter(1, $entity->idLib);
                  $res = $qb->getQuery()->getResult();
                  foreach ($res as $tr) {
                      $entity->tr[$tr->locale->idLocale] = $tr;
                  }
              }
          }
      }
      

      When this code is run (eg. getting the Library objects), I got a crash where getResult() is called:

      Fatal error: Call to a member function fetch() on a non-object in /home/thepianoguy/testproject/trunk/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php on line 126
      Call Stack
      #	Time	Memory	Function	Location
      1	0.0004	656080	{main}( )	../index.php:0
      2	0.1081	18760176	TApplication->run( )	../index.php:48
      3	0.2637	33817288	TApplication->runService( )	../TApplication.php:382
      4	0.2637	33817288	TPageService->run( )	../TApplication.php:1095
      5	0.2698	34788448	TPageService->runPage( )	../TPageService.php:444
      6	0.2715	34986768	TPage->run( )	../TPageService.php:498
      7	0.2716	34989128	TPage->processNormalRequest( )	../TPage.php:198
      8	0.3383	42770128	TControl->loadRecursive( )	../TPage.php:215
      9	0.3383	42770208	ContactUserAddEdit->onLoad( )	../TControl.php:1286
      10	0.3383	42771912	ContactUserAddEdit->loadData( )	../ContactUserAddEdit.php:56
      11	0.3452	43436904	Doctrine\ORM\AbstractQuery->getResult( )	../ContactUserAddEdit.php:124
      12	0.3452	43437296	Doctrine\ORM\AbstractQuery->execute( )	../AbstractQuery.php:366
      13	0.4160	47009328	Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll( )	../AbstractQuery.php:537
      14	0.4160	47011504	Doctrine\ORM\Internal\Hydration\ObjectHydrator->_hydrateAll( )	../AbstractHydrator.php:99
      

      If I comment the line 137 in Doctrine/ORM/Internal/Hydration/AbstractHydrator in _cleanup(), my code works fine:
      // $this->_stmt = null;

      I think there is a problem when using alredy used entity manager and query builder inside the postLoad event.

        Activity

        Hide
        Benjamin Eberlei added a comment -

        The hydrator is reused internally, this is potentially dangerous as I figure from your use-case.

        Show
        Benjamin Eberlei added a comment - The hydrator is reused internally, this is potentially dangerous as I figure from your use-case.
        Hide
        Benjamin Eberlei added a comment -

        A workaround is to re-registr the object hydrator under a new name

        $configuration->setHydrationMode("object2", "Doctrine\ORM\Internal\Hydration\ObjectHydrator");
        

        and use it in your query.

        $query->setHydrationMode("object2");
        
        Show
        Benjamin Eberlei added a comment - A workaround is to re-registr the object hydrator under a new name $configuration->setHydrationMode( "object2" , "Doctrine\ORM\Internal\Hydration\ObjectHydrator" ); and use it in your query. $query->setHydrationMode( "object2" );
        Hide
        Marco Pivetta added a comment -

        Marking as documentation issue, since the user has to be warned that `postLoad` has to use a dedicated hydrator to execute more load operations.

        Show
        Marco Pivetta added a comment - Marking as documentation issue, since the user has to be warned that `postLoad` has to use a dedicated hydrator to execute more load operations.
        Hide
        Guilherme Blanco added a comment -
        Show
        Guilherme Blanco added a comment - I fixed this issue in master as of https://github.com/doctrine/doctrine2/commit/8d13601e39d0fdefdd1d2c0a85704c440b8bdd37 Cheers, GB

          People

          • Assignee:
            Guilherme Blanco
            Reporter:
            Matevz Jekovec
          • Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: