Doctrine2 (Doctrine 2.1) eager loading in Symfony2

拜拜、爱过 提交于 2019-11-29 01:21:59

You're joining a table but you're not selecting anything from it. Add ->addSelect('a') to your query builder. Consider two following SQL queries to understand the difference:

SELECT a.id, a.title
FROM article a 
JOIN category c ON a.category_id = c.id 
WHERE a.id = 123;

SELECT a.id, a.title, c.id, c.name 
FROM article a 
JOIN category c ON a.category_id = c.id 
WHERE a.id = 123;

Eager/lazy joining has nothing to do with DQL queries. It defines what should be loaded when you use $articleRepository->find(123).

In the part where you try to "force eager loading" the problem might be that you use the fetchMode method with the wrong variable type for the $fetchMode argument. You pass a string 'EAGER' but the method doesn't expect a string but an integer.

The method expects constants from the ClassMetadata class:

/**
 * Specifies that an association is to be fetched when it is first accessed.
 */
const FETCH_LAZY = 2;

/**
 * Specifies that an association is to be fetched when the owner of the
 * association is fetched.
 */
const FETCH_EAGER = 3;

In the Doctrine documentation chapter 14.7.6.6. Temporarily change fetch mode in DQL you can see an example on how to use this:

$query->setFetchMode("MyProject\User", "address", \Doctrine\ORM\Mapping\ClassMetadata::FETCH_EAGER);

So pass either a reference to the constant or an integer that corresponds to the mode you want to use.

As it says in the doctrine docs, eager loading in this case won't make any difference because you have one-to-many relationship between Category and Article.

For one-to-many relations, changing the fetch mode to eager will cause to execute one query for every root entity loaded. This gives no improvement over the lazy fetch mode which will also initialize the associations on a one-by-one basis once they are accessed.

So contrary to what @Crozin has said, you can still do eager loading in DQL. If you have a one-to-one or many-to-one relationship, eager loading will solve the problem of making extra queries. However to solve your problem in this case you should use ->addSelect('a') as @Crozin mentioned.

It is a better solution because joins are a much more expensive process than a simple query. While it may seem inefficient, it isn't much of a waste, and quickly becomes more efficient when you aren't loading every bit of every related object.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!