mirror of
https://github.com/doctrine/orm.git
synced 2026-03-23 22:42:18 +01:00
Removing multiple entities does not invalidate Identity Map #5772
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 @tijsverkoyen on GitHub (Nov 14, 2017).
I have a weird problem, I do not know if I am handling this the correct way.
I have a method: existsComment, with the following code:
I have a record in my MySQL database with id=1. When I call
existsComment(1)it returns true. So far everything is ok.Next I delete the same entity with a custom method in my repository, see the code below:
The reason why I want to delete multiple comments at once is only for performance reason. In some case there can be 10000 comments that are spam, and we want to enable the user to delete them at once. If I use the
->remove()method on each Entity, it will result in 10000 queries. A single DELETE query will be more performant.But if I call the
existsCommentagain, it results intrue.If I look in the database the comments are all removed, so it probably exists only in the Doctrine cache.
If I inspect the UnitOfWork, and check the state of a removed Entity it is 1 (STATE_MANAGED), where I expect 4 (STATE_REMOVED).
So, my question is: what am I doing wrong? Is this intended behaviour? And if it is intended, what is the best way around this?
@fesor commented on GitHub (Nov 14, 2017):
Title is miss-leading. Identity map (which is part of unit of work) is not a cache, it is part of current state of unit of work. If you load something into UoW, then make something with it bypassing it, state will not be changed.
Since you are deleting your entities bypassing UoW, it has no information about it. So yes, this is intended behaviour.
This depends on context. First of all, why you need to load all this comments into UoW in the first place? If you are going to delete it via DELETE, then you could collect needed ids also via DBAL (DQL). In this case no entities will be loaded into UoW.
Also if you only need to check that record presents in database, it will be much cheaper (from performance point of view) to add another custom query:
This will not load any data into UoW.
@tijsverkoyen commented on GitHub (Nov 15, 2017):
The context: I discovered this while writing some tests. There I check if the entity exists (with the
existsCommentmethod), then I delete the comment (withdeleteMultipleById). And I expected the entity to be deleted.I really don't want to use get all the entities and delete them in a loop with the
->remove()method, from a performance point of view.So am I correct, if I state that there is no way to combine the use of UnitOfWork with custom queries thru the QueryBuilder? Or is there a way to "clear" the UnitOfWork?
PS: I changed the title, I'm not that familiar with all Doctrine vocabulary.
@alcaeus commented on GitHub (Nov 15, 2017):
You can either loop through all entities and
detachthem from the EntityManager or callclearwhich will either clear all entities or only those of the class you've passed. Either way,clearis a rather blunt tool you should be careful with.@tijsverkoyen commented on GitHub (Nov 15, 2017):
And what happens if you update an entity with the query builder? Will the Identity Map be updated? And if not, how could you work around that?
@Ocramius commented on GitHub (Nov 15, 2017):
It will not be updated: clearing the UnitOfWork is the safest approach
there.
On 15 Nov 2017 10:22, "Tijs Verkoyen" notifications@github.com wrote:
@tijsverkoyen commented on GitHub (Nov 15, 2017):
So clearing the full UnitOfWork instead of detaching the entities. I guess it will be refetched from the database when it is requested again?
@Ocramius commented on GitHub (Nov 15, 2017):
Correct
Marco Pivetta
http://twitter.com/Ocramius
http://ocramius.github.com/
On Wed, Nov 15, 2017 at 9:29 AM, Tijs Verkoyen notifications@github.com
wrote:
@tijsverkoyen commented on GitHub (Nov 15, 2017):
Thx guys for helping a noob ;-)