mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Unnecessary refresh() while acquiring pessimistick lock with find() leads to loosing changes done to entity #7572
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 @Arkemlar on GitHub (Nov 7, 2025).
Bug Report
Summary
Every time a pessimistic lock is requested via find(), Doctrine queries the database, and if the object is already hydrated, it updates it using refresh().
Now imagine we have two independent sections of code that require a similar lock. Here's what happens:
And there's no way to check whether a pessimistic lock was previously obtained on the entity instance.
Current behavior
Repeated calls to
find($id, LockMode::PESSIMISTIC_WRITE)result in the loss of object state due to overwriting in https://github.com/doctrine/orm/blob/3.5.x/src/EntityManager.php#L342Expected behavior
Preserve the lock state and do not call refresh() when the object has already acquired one.
If the object is already hydrated, but the lock is acquired for the first time, it is correct to call refresh() and reset its state; in such cases, all business logic should be executed after acquiring the lock.
How to reproduce
Prerequisites:
Problem demonstration:
When I replace Section B with this - everything fine:
In the last case, we see that the behavior of the find() function matches what most of us expect, as we know it uses identityMap to avoid unnecessary queries and reuses the state of the managed object. The behavior demonstrated in Section B violates this contract.