mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
DDC-2763: Inheritance. CTI & STI. Improve lazy load associated entity, when target entity in association mapping is not last leaf in class hierarchy. #3459
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @doctrinebot on GitHub (Oct 27, 2013).
Originally assigned to: @beberlei on GitHub.
Jira issue originally created by user strate:
If we look inside documentation, we can see this:
{quote}
There is a general performance consideration with Class Table Inheritance: If the target-entity of a many-to-one or one-to-one association is a CTI entity, it is preferable for performance reasons that it be a leaf entity in the inheritance hierarchy, (ie. have no subclasses). Otherwise Doctrine CANNOT create proxy instances of this entity and will ALWAYS load the entity eagerly.
{quote}
I think it can be improved, if we will load only discriminator column value for resolve target class name, instead of loading whole entity. When we perform query from root entity, dicriminator value is already present in fetched database row.
What do you think?
@doctrinebot commented on GitHub (Oct 27, 2013):
Comment created by @ocramius:
Queries to fetch the discriminator column cannot be avoided (that's a limitation we can't workaround as far as I know).
What can be improved is avoiding instantiation of the joined results, and instead keep a proxy and a copy of the data for deferred hydration. That would allow avoiding recursive queries which are seen quite often when referencing the root of a STI/JTI
@doctrinebot commented on GitHub (Oct 27, 2013):
Comment created by strate:
bq. Queries to fetch the discriminator column cannot be avoided (that's a limitation we can't workaround as far as I know).
Of course, but fetching the discriminator value will produce less overhead than loading whole entity (with recursive loading joined entities). And, when you querying from root entity (with mapped sicriminator column), discriminator value already present in db result row (no need to extra query for dicriminator value).
bq. What can be improved is avoiding instantiation of the joined results, and instead keep a proxy and a copy of the data for deferred hydration. That would allow avoiding recursive queries which are seen quite often when referencing the root of a STI/JTI
The result of my proposal will ability to get proxy class without loading whole entity.
@doctrinebot commented on GitHub (Jun 24, 2015):
Comment created by leca.bo:
IMHO useful proposal!
@flaushi commented on GitHub (Oct 11, 2018):
Hey, I have this problem, and have found a partial solution, see my SO post.
Briefly, I perform an eager DQL fetch join query for each leaf class, after that the select queries for each referenced entity are not necessary anymore because they are loaded already.
@Ocramius commented on GitHub (Oct 15, 2018):
@flaushi that doesn't help if you have a recursive association:
A DQL query like following will instantiate all parents with one query per parent:
Anyway, the original problem of this patch is now fixable, since ORM 3.0 uses ProxyManager. What we can do is eagerly load all scalar fields, and leave the associations as empty placeholder properties: once a property is read, the lazy-loading of the current proxy instance will replace the property with an association, in which scenario the query will be performed to determine the type of the associated value.
See https://github.com/doctrine/doctrine2/pull/6724
See https://github.com/doctrine/doctrine2/issues/6722
See https://github.com/doctrine/doctrine2/pull/6719
@Grafikart commented on GitHub (Feb 26, 2020):
I'm using Class Table Inheritance and I have to admit it's unexpected to have multiple queries (even with partials)
(I have Comment OneToMany Content, with Content not being a leaf)
This will indeed generate 2 queries. Could you point me in the direction (which class should I look into to solve this issue) ? Is there a way to prevent the field from being loaded (I know I won't need it for this query)
In the meantime, if someone find this issue the only workaround is to force partial load to prevent doctrine from reaching the relation hydratation part.