Orm: Bad format result when entityMapped and scalarResult in the same query with iterate() method

Created on 2 Mar 2016  路  11Comments  路  Source: doctrine/orm

I met a problem with Doctrine when I use addRootEntityFromClassMetadata and addScalarResult in the same native query.

$rsm = new ResultSetMappingBuilder($this->getEntityManager());
$rsm->addRootEntityFromClassMetadata('AppBundle\Entity\EntityFirst', 'entityFirst');
$rsm->addJoinedEntityResult('AppBundle\Entity\EntitySecond', 'entitySecond');
$rsm->addScalarResult('scalarFirst', 'scalarFirst');
$rsm->addScalarResult('scalarSecond', 'scalarSecond');

$query = $this->getEntityManager()->createNativeQuery("
    SELECT
        *,
        COUNT(id) AS scalarFirst,
        COUNT(id) AS scalarSecond
    FROM
        entityFirst
        LEFT JOIN entitySecond ON entityFirst.id = entitySecond.id_entityFirst
", $rsm);
foreach ($query->iterate() as $row) {
    var_dump($row);
}

The first row will have a good structure :

array(3) {
    [0] =>
        class AppBundle\Entity\EntityFirst#1225 (52) {
            ...
        }
    'scalarFirst' => int(4120)
    'scalarSecond' => int(4120)
}

But each others rows have a bad format.
The second row:

array(2) {
    [0] =>
        class AppBundle\Entity\EntityFirst#1225 (52) {
            ...
        }
    [2] => array(2) {
        'scalarFirst' => int(4120)
        'scalarSecond' => int(4120)
    }
}

The third row:

array(2) {
    [0] =>
        class AppBundle\Entity\EntityFirst#1225 (52) {
            ...
        }
    [3] => array(2) {
        'scalarFirst' => int(4120)
        'scalarSecond' => int(4120)
    }
}

...

The fifth row:

array(2) {
  [0] =>
    class AppBundle\Entity\EntityFirst#1225 (52) {
        ...
    }
  [5] => array(2) {
    'scalarFirst' => int(4120)
    'scalarSecond' => int(4120)
  }
}

As you can see, some index disappear and the index where scalar results are is an index which increase each line read.

Is there something to tell the hydrationMode of result from a native query or something else ?

Bug

All 11 comments

Does this behavior present itself only when using iterate(), or also with getResult()?

Our query will have to manage a large result of rows. So getResult() will not be adapt.

After check, getResult() has a good structure.

I faced the same problem with iterate() method only, in my research these statements collide with this one.

Any possible solution for that?

I've just faced the same problem with a DQL query and iterate method().

Maybe you should rename the issue title to include "iterate() method" in order to have a better visibility.

Any news about this issue?

My temporary solution is: use an index to check the good cell of the array.

$i = 0;
foreach ($query->iterate() as $row) {
    $i++;
    if ($i !== 1) {
        $row = array_merge($row, $row[$i]);
        unset($row[$i]);
    }
    var_dump($row);
}

Results for each rows:

array(3) {
    [0] =>
        class AppBundle\Entity\EntityFirst#1225 (52) {
            ...
        }
    'scalarFirst' => int(4120)
    'scalarSecond' => int(4120)
}

@caudurieauelma could you please send us a failing test case that reproduces that behaviour? It would help us a lot to identify and fix the issue you're describing.

You can find examples on https://github.com/doctrine/doctrine2/tree/388afb46d0cb3ed0c51332e8df0de9e942c2690b/tests/Doctrine/Tests/ORM/Functional/Ticket

vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
line 472
// PATH C: Its a root result element
$this->rootAliases[$dqlAlias] = true; // Mark as root alias
$entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0;

Looks like here is the problem

Fix would be
$entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: $dqlAlias + '_' + $entityName ;
using the alias and / or the entityName would be more intuitive to resolve the results
Hope this helps to fix this quickly

Fix would be
$entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: $dqlAlias + '_' + $entityName ;
using the alias and / or the entityName would be more intuitive to resolve the results
Hope this helps to fix this quickly

We need a test case to verify a problem in first place. Patches without tests are not considered.

@Ocramius
Thanks for the quick reply
The test case would be the following

$repo = $em -> getRepository( 'entityA' ) 
$query = $repo->createQueryBuilder( 'a' ) 
-> select ( 'a, count( a.id ) as count , b' ) 
->leftJoin( 'entityB' , 'b', 'with' , 'a.id = b.a' ) 
->setFirstResult(0)
->setMaxResults(1);
$results = $query->getQuery()->getResult();

Test
Fail test if result count has more than 1
Fail if entityA key in result should be either Alias or Entity name not 0
Fail if entityB key in result should be either Alias or Entity name not 0
Actual Results

[ 
[0] => {
   [0] => { entity A } 
}, 
[1] => { 
   [0] => { entityB } , 
   [count] => 10 
},
]

Expected results

[ 
[0] => {
   [a] => { entity A } ,
   [b] => { entityB } , 
   [count] => 10 
},
]

Hope this helps resolve this isssue

Was this page helpful?
0 / 5 - 0 ratings