Reputation: 1140
I am selecting 3 entities via regular LEFT JOIN in DQL. They are related via join tables which also have entities defined for them as well as annotated relationships. The query executes without issue but my results are returned as a flat array. I would expect an array with the three entities as array elements for each index:
SELECT e1, e2, e3 FROM AppBundle:EntityOne
JOIN AppBundle:JoinEntityOneWithTwo e1_2 WITH e1_2.entity1 = e1.id
JOIN AppBundle:EntityTwo e2 WITH e1_2.entity2 = e2.id
JOIN AppBundle:JoinEntityOneWithThree e1_3 WITH e1_3.entity1 = e1.id
JOIN AppBundle:EntityThree e3 WITH e3.id = e1_3.entity3
WHERE e1.some_field IN ('some','values','in','e1');
When I call getResult()
on the query, either hydrating as an object or an array, I get a flat results set:
array(
/AppBundle/Entity/EntityOne ( ... ),
/AppBundle/Entity/EntityTwo ( ... ),
/AppBundle/Entity/EntityThree ( ... ),
/AppBundle/Entity/EntityOne ( ... ),
/AppBundle/Entity/EntityTwo ( ... ),
/AppBundle/Entity/EntityThree ( ... ),
/AppBundle/Entity/EntityTwo ( ... ),
/AppBundle/Entity/EntityThree ( ... ),
/AppBundle/Entity/EntityOne ( ... ),
)
I would expect, or like to have a multi dimensional array:
Array(
[0] => Array(
[0] /AppBundle/Entity/EntityOne,
[1] /AppBundle/Entity/EntityTwo,
[2] /AppBundle/Entity/EntityThree
),
[1] => . . .
)
The results are not related by row. Nor are they in any predictable order that I can group them by with array_chunk()
The generated sql runs fine. The DQL returns accurate results -- they're just not formulated in a way that I would expect. I am following Doctrines (elusive) documentation on eager loading joins:
This question is very similar to
Doctrine DQL returns multiple types of entities
But my select order is different as my join tables are many-to-many. Much thanks!
A variant of this question was asked:
Getting Doctrine DQL results the SQL way
I'm pretty surprised that doctrine does not support eager loading via join table.
Upvotes: 4
Views: 3647
Reputation: 20852
Call getScalarResult()
instead of getResult()
on your query and you will get all fields of all joined tables merged into one array per record:
# Replace this call ...
$query->getQuery()->getResult();
# ... by that call ...
$query->getQuery()->getScalarResult();
Upvotes: 3
Reputation: 1140
Here is the best that I could come up with:
//in my entity repository:
public function getFoo($hydrate = true) {
$sql = "SELECT e1, e2, e3 FROM entity_one
JOIN entity_one_entity_two e1_2 ON e1_2.entity_one_id = e1.id
JOIN entity_two e2 ON e1_2.entity_two_id = e2.id
JOIN entity_one_entity_three e1_3 ON e1_3.entity_one_id = e1.id
JOIN entity_three e3 ON e3.id = e1_3.entity_three.id
WHERE e1.some_field IN ('some','values','in','e1')";
$stmt = $con->prepare($sql);
$stmt->execute();
return ($hydrate)
? $this->hydrateResponses($stmt->fetchAll(PDO::FETCH_ASSOC))
: $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function hyrdateResponses($responses) {
//call find by ids on repositories from array.
}
This works great because you're performing 3XN the number of queries when you're only trying to get results from one!
Upvotes: 1