Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
584 views
in Technique[技术] by (71.8m points)

doctrine orm - Doctrine2 one-to-one relation auto loads on query

I have a query that looks like this:

My user entity has a one-to-one relation that looks like this:

/**
 * @var UserProfile
 *
 * @ORMOneToOne(targetEntity="UserProfile",mappedBy="user")
 */
private $userProfile;

Anytime I make a query to select multiple user objects, it creates an additional select statement per user to query for the UserProfile data even though I am not accessing it through a get method. I don't always need the UserProfile data, and I certainly don't want to load this data every single time I'm displaying a list of users.

Any idea why these queries are executed at run time?

question from:https://stackoverflow.com/questions/12362901/doctrine2-one-to-one-relation-auto-loads-on-query

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is solutions explain with details :

https://groups.google.com/forum/#!topic/doctrine-user/fkIaKxifDqc

"fetch" in the mapping is a hint, that is, if it is possible Doctrine does that, but if its not possible, obviously it does not. Proxying for lazy-loading is simply not always possible, technically. The situations where its not possible are:

1) one-to-one from inverse to owning side (appears only in bidirectional one-to-one associations). Precondition a) above can not be met. 2) one-to-one/many-to-one association to a hierarchy and the targeted class has subclasses (is not a leaf in the class hierarchy). Precondition b) above can not be met.

In these cases, proxying is technically not possible.

Your options to avoid this n+1 problem:

1) fetch-join via DQL: "select c,ca from Customer join c.cart ca". Single query but join, however, joins on to-one associations are relatively cheap.

2) force partial objects. No additional queries but also no lazy-load: $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)

3) if an alternative result format (i.e. getArrayResult()) is sufficient for a use-case, these also avoid this problem.

Benjamin had some ideas about automatic batching of these loads to avoid n+1 queries but this does not change the fact that proxying is not always possible.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...