mirror of
https://github.com/doctrine/orm.git
synced 2026-04-24 06:58:19 +02:00
DDC-74: Updates get lost when Lifecycle Events (@PreUpdate) are invoked #90
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 @doctrinebot on GitHub (Oct 29, 2009).
Jira issue originally created by user nicokaiser:
When Lifecycle Events are invoked on entity update (@PreUpdate), the entity is not updated properly in the database.
This code creates a *User* object, sets its name to "Bob" and its value to empty, then updates the object and updates the name to "Alice".
{quote}
$user = new User;
$user->setName('Bob');
$user->setValue('');
$em->persist($user);
$em->flush();
$user->setName('Alice');
$em->flush();
{quote}
However, when the User class has a @PreUpdate event that e.g. sets the *value* to "Hello World", the name change gets lost and only the value is updated by the second flush() call.
This is a critical bug which prevents creation of entities that simulate the "Timestampable" behaviour of Doctrine 1.x...
@doctrinebot commented on GitHub (Nov 2, 2009):
Comment created by @beberlei:
I think this might be a hen-egg problem.
@PreUpdate is only invoked after it is calculated that a change occured on all those entities that have updates. After a change in @PreUpdate events there would have to be another calculation of changes on all those entities, which would probably mean a significant performance hit.
@doctrinebot commented on GitHub (Nov 13, 2009):
Comment created by rickdt:
I may not know all the consequences of this, but I think I have a fix for this bug.
In the class ORM\UnitOfWork
As I understand it, computeSingleEntityChangeSet() is called to update the changeset and _originalEntityData is set to the current values.
But, I see that the old changes are lost.
If i modify the function computeSingleEntityChangeSet to merge the changeset, it works.
At line 656 replace
By :
Here is my test case :
AND The preUdate :
@doctrinebot commented on GitHub (Nov 13, 2009):
Comment created by romanb:
Indeed this looks like a good fix except that the addition has to be the other way around so that when the same field is changed twice, first before the flush and then in a lifecycle callback/event the change from the callback prevails.
I will work on this and write a test for it.
Thanks Eric.
@doctrinebot commented on GitHub (Nov 13, 2009):
Comment created by romanb:
Fixed now.
Thanks Nico for reporting and thanks Eric for the suggestion!
@doctrinebot commented on GitHub (Nov 13, 2009):
Issue was closed with resolution "Fixed"