2c75209ce3adf262cd3162704a81ef3dc4b8dec2
Parser::$identVariableExpressions was keyed by alias and held a single SelectExpression per alias, so listing the same identification variable twice in a SELECT clause made the second node overwrite the first. fixIdentificationVariableOrder() only unsets and re-appends the nodes it knows about, so the forgotten first node stayed at the head of the select clause, ahead of its own parent. The hydrator then reached the child before the parent existed in resultPointers, took the "parent object of relation not found" branch in ObjectHydrator and unset the 'fetched' hint for the association. Because the hints are only rebuilt in prepare(), the association stayed marked as not fetched for the rest of the hydration run: the fetch join was silently dropped and every parent's collection lazy loaded, while the query still returned correct data. Track every select expression per identification variable and move all of them when reordering, so duplicates are re-appended together behind their parent, in declaration order. With a single occurrence per alias the inner loop runs once and the behaviour is unchanged.
Languages
PHP
100%