mirror of
https://github.com/doctrine/orm.git
synced 2026-03-23 22:42:18 +01:00
fetch-joined native sql associations do not seem to function as described #5938
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 @yurtesen on GitHub (Mar 29, 2018).
In documentation examples is a nice example of how to map native SQL with a join. I mean the example right under the line
Consequently, associations that are fetch-joined do not require the foreign keys to be present in the SQL result set, only associations that are lazy.However I found out that this does not seem to work. 3 months ago I made a question at stackoverflow with 0 responses. I now managed to solve the issue but it seems to conflict with what documentation says.
I have 2 tables.
storeandstore_product.In
Storeentity I have:and in
Store\Productentity I have composite index with (store_id,product_id). I have (also price field, which is omitted below for brevity):I am trying to join
store_producttable. I am using the following query which returns 1 result as the test case.SELECT st.id, st.name, stp.store_id, stp.product_id, stp.price FROM store st LEFT JOIN store_product stp ON st.id = stp.store_id WHERE st.id=1 LIMIT 1;returns something like:
I setup the result set mapping as follows:
I am getting error:
Notice: Undefined index: storeI tried several different variations, such as changingstorewithidetc. and result is either empty product association or error.The only way to fix the issue was to replace the lines:
$rsm->addFieldResult('stp','store_id', 'store');
$rsm->addFieldResult('stp','product_id','product');
with:
$rsm->addMetaResult('stp', 'store_id', 'store_id', true);
$rsm->addMetaResult('stp', 'product_id', 'product_id', true);
and I had to set the 3rd
$isIdentifierColumnparameter to true.Documentation says when query readily fetches the results, there is no need for foreign keys. So this is a bug or what is going on?
@Ocramius commented on GitHub (Mar 29, 2018):
Identifiers are indeed meta results, not field results. Can you maybe link the portion of the docs that you found to be buggy? See
1afbf141fc/docs@yurtesen commented on GitHub (Mar 29, 2018):
4509c770da/docs/en/reference/native-sql.rstExample just under the text
Consequently, associations that are fetch-joined do not require the foreign keys to be present in the SQL result set, only associations that are lazy.There it uses
$rsm->addFieldResult('a', 'address_id', 'id');for the id values. Hmm?@Ocramius commented on GitHub (Mar 29, 2018):
Hmm, yeah, that looks confusing and also confusing to read.
What happens if you only fetch the FK (from the owning side of the association) is that a proxy will be instantiated and kept un-initialized. Also, I think the examples were not designed with one-to-many in mind. In your case,
@ORM\Id()and@ORM\ManyToOne()appear to be on the same field, in which case aResultSetMapping#addMetaResult()is required to create an object reference, and you don't haveResultSetMapping#addFieldResult()because that's not a field, but an association.Does that make sense?
@yurtesen commented on GitHub (Mar 29, 2018):
From documentation what I understood was that
AddressandUserhad one-to-one relation. When the example usesaddJoinedEntityResult()I understood that it will make an object reference to Address. It saysAddress is hydrated into the User::$address property.So actually are you sure the code in the example even works?In either case, documentation is perhaps unnecessarily confusing. Is there any reason why one shouldn't use only
addMetaResult()even if it is NOT lazy fetched? For example in my case I useaddMetaResult()and doctrine does not seem to re-fetch the joined entity. When I query$productsfrom Store, I get only the 1 product I selected in the query. It is NOT using the proxy functionality.@Ocramius commented on GitHub (Mar 29, 2018):
No, I'm not, but I won't get to check it either right now.
Agreed: the entire section should be trashed and made part of the
ResultSetMappingdocblocks instead.An
addMetaResult()is always needed when a fetched resultset field is actually a reference: doesn't matter if lazy or not.Correct: the hydration already happened, so no proxying needed.
@yurtesen commented on GitHub (Apr 3, 2018):
@Ocramius sorry I was sick and couldn't respond. Thanks for your responses. Hopefully this at least would be useful to somebody who has the same problem or at some point the documentation could be updated. Thanks!