mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
IdentityMap #7196
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 @tasselchof on GitHub (Aug 2, 2023).
Bug Report
Summary
I am getting an exception about entity in identity map
Current behavior
While adding an entity of class Proxy was already present for the same ID. This exception\nis a safeguard against an internal inconsistency - IDs should uniquely map to\nentity object instances. This problem may occur if:\n\n- you use application-provided IDs and reuse ID values;\n- database-provided IDs are reassigned after truncating the database without \n clearing the EntityManager;\n- you might have been using EntityManager#getReference() to create a reference \n for a nonexistent ID that was subsequently (by the RDBMS) assigned to another \n entity. \n\nOtherwise, it might be an ORM-internal inconsistency, please report it.
How to reproduce
I am not sure how to reproduce it, but I am getting this in that case:
I am getting some values from database with native query (I am using composite keys) and generating reference from it (I can fetch from database this value - no matter, everything is fine):
I am using this reference in further request and if I generate spl_object_id it's always same object. But later I am fetching one another entity from database:
This entity contains property productOffer with is linked with the same ids (so technically it contains same object).
And if I am checking
spl_object_id($acceptanceItem->getProductOffer())it's different object.I am using the value of this object in preFlush to populate search index:
And exactly here I am getting this exception:
Expected behavior
I suppose should be the same object as it is already loaded before flush.
@greg0ire commented on GitHub (Aug 3, 2023):
Please learn how to format Github messages.
@derrabus commented on GitHub (Aug 3, 2023):
I've fixed that for you. 😉
@derrabus commented on GitHub (Aug 3, 2023):
Looks like two proxies have been created for the same entity and one of the proxies is being resolved during the
preFlushevent in your case. This looks like an interesting edge case of your identity map corruption detection, @mpdude. Can you take a look?@tasselchof commented on GitHub (Aug 3, 2023):
I m sorry, I was very limited in time, but I thought it’s important to create an issue because it might impact not only our software.
This is not in our code but this is something, on the first look, that os affecting doctrine itself.
I think if I will do simple test case: pull Offer from database and after this try to pull same one from proxy it will be the same problem.
@mpdude commented on GitHub (Aug 3, 2023):
I don't fully understand how to reproduce the issue.
I have tried to put that into #10873, but that's OK so far.
So, what is the missing piece?
@tasselchof commented on GitHub (Aug 3, 2023):
@mpdude I tried to play a bit with reproducing an issue and rebuild annotations to be closer to live code.
The problem is that this part of the code is set to refactoring (it's very old and bad done), but it's causing this issue and I want to try to figure out why. There is 3 blocks in one function. First block writing location logs, second block updating barcodes of the offer and third is updating quantity in item. If I comment block 1 or 2 everything is fine. They just can't work together.
Adding this reference in any part of the code causing this exception as well.
@tasselchof commented on GitHub (Aug 4, 2023):
There is something here... I found another case in the code. Worked like that: there is a part of logic that do some modifications and flushes the result. After flush getting reference causing this exception. And I broke down this to one case: I have order that has collection of orderProducts, each of those has a reference to Offer. So If I do like that:
$productOffer->getType() causing and exception ($productOffer is a proxy).
@tasselchof commented on GitHub (Aug 4, 2023):
@mpdude can you take a look? productOffer that I got from the collection is not Proxy, but reference is proxy, test is here: tests/Doctrine/Tests/ORM/Functional/Ticket/GH10868Test_2.php. Maybe it's something?
@mpdude commented on GitHub (Aug 5, 2023):
@tasselchof #10873 contains the code as you suggest.
$referenceis a reference to an instance ofGH10868Offer, whereas$order->orderProducts->first()is an instance ofGH10868OrderProduct.To me, this seems logically wrong, so no surprise the test is failing.
@tasselchof commented on GitHub (Aug 5, 2023):
@mpdude no, there is nothing wrong in logic, check the assertion:
self::assertSame($reference, $orderProductFromOrder->productOffer);I am taking first order product and comparing reference and productOffer of first orderProduct. They should be the same. But they are not.
@mpdude commented on GitHub (Aug 5, 2023):
@tasselchof Let's continue the discussion in #10873, so we're closer to the code and can make sure we're on the same page.
@tasselchof commented on GitHub (Aug 5, 2023):
@mpdude I've found how this is happening (spoiler: I've updated test in it passing well). I have in Shop entity __toString magic method where I am returning "name" of the shop (if it is set). So when UnitOfWork here:
a616914887/lib/Doctrine/ORM/UnitOfWork.php (L1709-L1724)trying to get key (in my case composite key) it is getting something like "123 Store" instead of "123 1" like it should. Such a weird id is missing in the identity map and this is leading to attempt to register it once more.And removing magic method causing this:
So this is a specific issue for an entity, that has a composite key and one of the composite key components is an object.
@conradfr commented on GitHub (Aug 8, 2023):
FWIW I get this error when I try to create an entity in a submit form in Symfony where I create the object before and set the id (manual id).
The code has not changed since "composer upgrade" and was working before.
Downgrading to doctrine/orm 1.15.5 did the trick.
Something like
@mpdude commented on GitHub (Aug 9, 2023):
@conradfr the error message may be the same, but since you’re using application-provided IDs it seems to me this is a slightly different case.
Please open a dedicated issue (or better, PR) and provide a test case to reproduce. Have a look at the
GHxxxTest.phpfunctional test cases in this repo, that should help you get going. I don’t think (at this time) Symfony has anything to do with it. Leave those parts (form handling etc) out.