mirror of
https://github.com/doctrine/orm.git
synced 2026-03-23 22:42:18 +01:00
Hydration error with oneToMany relation indexed by id #7562
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 @danfraticiu on GitHub (Oct 18, 2025).
Bug Report
Summary
I have this recurring intermittent hydration issue since I've upgraded
doctrine/ormfrom 2 to 3 (starting with 3.3.3, currently on 3.5.2). ObjectHydrator.php:502 throwsErrorException: Warning: Undefined array key "id_11"How to reproduce
Unable to reproduce, error only happens occasionally, inside the messenger handlers on the async queue (Doctrine transport if that matters), the error does not trigger if the worker restarts and retries the message. Also I was not able to reproduce it locally.
Stack trace:
My application code that triggers the error is this:
There
serviceAgreementsis an index by id oneToMany relation (<one-to-many field="serviceAgreements" target-entity="Shift\Domain\ServiceAgreements\ServiceAgreement" mapped-by="client" index-by="id" orphan-removal="true" fetch="EXTRA_LAZY">). The same error happens with other oneToMany relations.ObjectHydrator::hydrateRowData receives a row like this:
notice the row has key
id_29but ORM expectsid_10.@danfraticiu commented on GitHub (Oct 18, 2025):
After some deep(er) diving, I managed to reproduce the issue locally: is trigger by modifying doctrine filters (confirmed with
Gedmo\SoftDeleteable\Filter\SoftDeleteableFilterand a blank filter created just to debugging).Undefined array key@danfraticiu commented on GitHub (Oct 20, 2025):
I managed to isolate the issue and reproduce it, it happens when:
OneToManyrelation and the child is a single table inheritance entity\Doctrine\ORM\Query\ResultSetMapping::addIndexByselects the first alias it finds (src/Query/ResultSetMapping.php:263) , which is no longer the alias in the SQL query.The solution:
in
\Doctrine\ORM\Query\ResultSetMapping::addIndexByselect the last alias found for the index field. But I'm not sure if this will cause issues in other situations as I'm not very familiar with the internals of the ORM. What I can say for sure is that it doesn't brake any of the tests. 🤷I will create a PR soon.
@perk11 commented on GitHub (Nov 1, 2025):
Also experiencing this issue. In my case it's caused by disabling and enabling the filter in the loop
@greg0ire commented on GitHub (Nov 1, 2025):
I just authorized the CI to run the code you submitted in #12228, and it actually breaks tests.
@perk11 it would be great if you could contribute a failing test based on that scenario or on the scenario described by @danfraticiu , to go with #12228
@igrizzli commented on GitHub (Nov 4, 2025):
I have researched this issue:
In https://github.com/doctrine/orm/blob/3.5.x/src/Persisters/Entity/BasicEntityPersister.php#L1259 we are adding entity result multiple times if we are changing filter state in runtime.
May be it have sense to clear RSM before populating it second time?
@perk11 commented on GitHub (Nov 4, 2025):
I work with @igrizzli. Can someone please review if the fix suggested by him makes sense? We can provide a PR with the fix and the test then.
@danfraticiu commented on GitHub (Nov 10, 2025):
@greg0ire I've updated my PR with a different solution that doesn't seem t break the tests, not sure this is the proper solution… feels more like a workaround, but I'm not familiar enough with the code base to be sure.
I tried to come up with a function test that reproduces the issue, but I'm pretty sure you'll have to touch a real DB to trigger it.
@greg0ire commented on GitHub (Nov 10, 2025):
@danfraticiu That's not a problem, our test suite touches real databases. By default, when you run it on your dev env, it will use SQLite.
@tomme87 commented on GitHub (Jan 14, 2026):
I have the same issue with doctrine 2.20.9. If I revert back to 2.20.3 it works, but anything after that fails.
@tomme87 commented on GitHub (Jan 16, 2026):
If anyone have a temporary workaround it would be very much appreciated.