Reputation: 2121
Think of this class:
class Person {
/**
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Person", fetch="EXTRA_LAZY")
* @ORM\OrderBy({"name" = "ASC"})
*/
public $friends;
/**
*
* @var Person
* @ORM\ManyToOne(targetEntity="Person")
*/
public $bestFriend;
}
I have to iterate a lot over all Persons, so I'd like to fetch join them all at once. To save memory, I have to do this partially.
So what I can do is:
$this->em->createQuery('SELECT partial p.{id, name, bestFriend} FROM Person p')->getResult();
This is cool, after this query, all persons are in the UoW, and I can traverse the graph via $aPersion->bestFriend->bestFriend
without creating an additional query to the DB, since all Persons are in memory.
However, this does not work with the ToMany association. Adding friends
to the partial select gives an error. If I want to iterate over all friends, this will first create a query to the join table...
How can I realise the full hydration of the friends
-ToMany-assotiation with one query? Maybe a second query could help? Or a clever join clause?
Thanks in advance!
Upvotes: 1
Views: 43
Reputation: 2121
@DirkJFaber your answer was right,
in terms of DQL here is my solution:
$this->em->createQuery('
SELECT partial p.{id, name, bestFriend}, f FROM Person p JOIN f.friends f')->getResult();
Upvotes: 0
Reputation: 4701
I would create a query in PersonRepository.php
with a leftJoin
and a addSelect
like so:
$qb = $this->em->getRepository('App:Person')
->createQueryBuilder('p')
->leftJoin('p.friends', 'friends')
->select('partial p.{id, name, bestFriend}'}
->addSelect('partial friends.{id, name}') // Retrieve what you want here
->getQuery()->getResult();
return $qb;
I have not tested this, but believe it should work.
Upvotes: 1