mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
DDC-1361: DQL Hydrate issues with PK composed with composite FK seemingly making collections loaded twice #1707
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 (Sep 4, 2011).
Originally assigned to: @beberlei on GitHub.
Jira issue originally created by user cammanderson:
Environment/Scenario:
ENTITIES:
Page Entity (page)
Elements Entity (element)
ElementVersion Entity (elementVersion)
Repository
When using my Node Repository I do a DQL with all the joins, e.g.
DQL: SELECT page, element, elementVersions FROM page JOIN page.elements AS element JOIN page.elementVersion AS elementVersion WHERE page.id = :pageId.
By doing this all the data is loaded correctly. This is shown by doing a var_dump on a HYDRATE_ARRAY. The structure is correct. There is one thing that appears missing elementVersion.element, therefore not having a complete PK present (TBD). I would think that there should be a reference back to the parent (element).
I then switched back to hydrating my entity objects as normal. I should have loaded all the data into the collections therefore stopping any need to do subsequent DB calls.
Problem/Bug
When I access the collection for the versions (e.g. page.elements.elementVersions) the elementVersions are reloaded again from the database. (e.g. A new SQL call is made to the server), even though my first join had loaded the data.
I believe that when it is using a FK in the PK composition it is not correctly seeing it has loaded the data already.
Weird Behaviour
If I do a DQL that joins the relationship back, I can avoid the database reloading the collection again:
SELECT page, element, elementVersion, elementVersionElement FROM page JOIN page.elements AS element JOIN page.elementVersions AS elementVersion JOIN elementVersion.element AS elementVersionElement WHERE page.id = :pageId.
By joining the table that is used for the FK/PK scenario back onto itself it prevents another SQL call being made when I attempt to access page.elements.elementVersions.
If I switch back to HYDRATE_ARRAY, I can see that now the elementVersions have the element variable, and it appears that this allows it to identify that it has it in the collection and no-longer needs to re-run SQL to locate the object again.
This results in unavoidable additional SQL calls for each element that exists on the page (scales proportionate to number of elements).
My Thoughts
I am thinking that in the hydrate process it is not setting the FK relationship of elementVersion.element, causing Doctrine to attempt to re-run SQL to obtain the collection again (maybe because it thinks that the objects do not have valid/complete PK). I think somewhere the mapping when it creates the objects is just missing the bit where the proxy gains a value for this property back to the parent.
@doctrinebot commented on GitHub (Sep 4, 2011):
Comment created by cammanderson:
I missed some backwards links between the element and the page.
@doctrinebot commented on GitHub (Sep 4, 2011):
Comment created by cammanderson:
I am developing a test case for this issue. Will share github link. thanks
@doctrinebot commented on GitHub (Sep 5, 2011):
Comment created by cammanderson:
Realised when I was doing PHP Unit Testing that I was getting some index undefined issues. It was around the generation of Hash values in the ObjectHydrator:217.
It was attempting to look at the $data for the FK element. In my example: undefined index element. By making it look up the associationMappings for the field name element it would be referencing the correct field value.
Updated around lines 217 as follows:
Not sure of the practice to submit a pull request. I am assuming I need corresponding test cases?
@doctrinebot commented on GitHub (Sep 5, 2011):
Comment created by cammanderson:
Found this was a duplicate issue of DDC-1300.
@doctrinebot commented on GitHub (Sep 5, 2011):
Issue was closed with resolution "Fixed"