Search code examples
symfonyormdoctrine-ormdoctrinedql

get doctrine to select entities without all associations


my user entity has a couple of associations

    oneToMany:
    images:
        targetEntity: Image
        mappedBy: user
    posts:
        targetEntity: Post
        mappedBy: user
        fetch: EXTRA_LAZY
    postcomments:
        targetEntity: Postcomment
        mappedBy: user
        fetch: EXTRA_LAZY

i want to select a specific user with all his posts and images, but not his postcomments. This is the query I use:

        $qb = $em->createQueryBuilder()
        ->select(array('u', 'p', 'i'))
        ->from('AppBundle:User', 'u')
        ->leftJoin('u.posts', 'p')
        ->leftJoin('u.images', 'i')
        ->where('u.id = :id')
        ->setParameter('id', $id);

However the result returned contains all the other associations aswell. Same as if I just select u and delete the joins.

How can I select only certain associations to be in the result?

Here is the full code of the api call

 public function getAction($id)
 {
    $em = $this->getDoctrine()->getEntityManager();

    $qb = $em->createQueryBuilder()
        ->select(array('u', 'p', 'i'))
        ->from('AppBundle:User', 'u')
        ->leftJoin('u.posts', 'p')
        ->leftJoin('u.images', 'i')
        ->where('u.id = :id')
        ->setParameter('id', $id)
        ->getQuery();

    $users = $db->getOneOrNullResult();
    $view = $this->view($users);

    return $this->handleView($view);
}`

Solution

  • I think you're misled by Doctrine's lazy loading feature.

    When you do

    $user->getPostcomments();
    

    and it returns you the collection of Postcomments, it still doesn't mean it has been fetched from DB along with the user itself.

    Lazy loading takes place here. It means that it's loaded on the first access attempt to this collection. It's not really fetched until you use it. ;-)

    By default Doctrine sets fetch: LAZY mode which works as mentioned above. You've used EXTRA_LAZY which has some additional features. In this case when you attempt to access particular element of collection (or a slice), Doctrine still won't load whole collection, but only a requested element or subset if slice() method it used. That's sometimes useful, but sometimes it may be cause of performance issues. You should be aware of difference between LAZY and EXTRA_LAZY.