-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix broken changeset computation for entities loaded through fetch=EAGER + using inheritance #10884
Conversation
5cb01e6
to
c58623c
Compare
66c4c76
to
70a969b
Compare
6dcf304
to
38a1367
Compare
@eXsio does this change fix it for you? |
38a1367
to
efbe22f
Compare
@mpdude yup, that does it, the tests are green :) |
One thing I am wondering ( as a total ignorant, so I may be completely off here :) ) but is there a valid scenario when the Just a thought. |
…ies loaded through fetch=EAGER + using inheritance doctrine#10880 reports a case where the changes from doctrine#10785 cause entity updates to be missed. Upon closer inspection, this change seems to be causing it: https://github.com/doctrine/orm/pull/10785/files#diff-55a900494fc8033ab498c53929716caf0aa39d6bdd7058e7d256787a24412ee4L2990-L3003 The code was changed to use `registerManaged()` instead, which basically does the same things, but (since doctrine#10785) also includes an additional check against duplicate entity instances. But, one detail slipped through tests and reviews: `registerManaged()` also updates `\Doctrine\ORM\UnitOfWork::$originalEntityData`, which is used to compute entity changesets. An empty array `[]` was passed for $data here. This will make the changeset computation assume that a partial object was loaded and effectively ignore all field updates here: https://github.com/doctrine/orm/blob/a616914887ea160db4158d2c67752e99624f7c8a/lib/Doctrine/ORM/UnitOfWork.php#L762-L764 I think that, effectively, it is sufficient to call `registerManaged()` only in the two cases where a proxy was created. Calling `registerManaged()` with `[]` as data for a proxy object is consistent with e. g. `\Doctrine\ORM\EntityManager::getReference()`. In the case that a full entity has to be loaded, we need not call `registerManaged()` at all, since that will already happen inside `EntityManager::find()` (or, more specifically, `UnitOfWork::createEntity()` called inside it). Note that the test case has to make some provisions so that we actually reach this case: * Load an entity that uses `fetch="EAGER"` on a to-one association * That association being against a class that uses inheritance (why's that?)
efbe22f
to
687b1e2
Compare
I've fixed the PHPCS failure for you. ✌🏻 |
#10880 reports a case where the changes from #10785 cause entity updates to be missed.
Upon closer inspection, this change seems to be causing it:
https://github.com/doctrine/orm/pull/10785/files#diff-55a900494fc8033ab498c53929716caf0aa39d6bdd7058e7d256787a24412ee4L2990-L3003
The code was changed to use
registerManaged()
instead, which basically does the same things, but (since #10785) also includes an additional check against duplicate entity instances.But, one detail slipped through tests and reviews:
registerManaged()
also updates\Doctrine\ORM\UnitOfWork::$originalEntityData
, which is used to compute entity changesets. An empty array[]
was passed for $data here.This will make the changeset computation assume that a partial object was loaded and effectively ignore all field updates here:
orm/lib/Doctrine/ORM/UnitOfWork.php
Lines 762 to 764 in a616914
I think that, effectively, it is sufficient to call
registerManaged()
only in the two cases where a proxy was created.Calling
registerManaged()
with[]
as data for a proxy object is consistent with e. g.\Doctrine\ORM\EntityManager::getReference()
.In the case that a full entity has to be loaded, we need not call
registerManaged()
at all, since that will already happen insideEntityManager::find()
(or, more specifically,UnitOfWork::createEntity()
called inside it).Note that the test case has to make some provisions so that we actually reach this case:
fetch="EAGER"
on a to-one association