DDC-74: Updates get lost when Lifecycle Events (@PreUpdate) are invoked #5252

doctrinebot opened this Issue Oct 29, 2009 · 5 comments

1 participant


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".

$user = new User;

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...


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.


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

$this->_entityChangeSets[$oid] = $changeSet;

By :

    $this->_entityChangeSets[$oid] += $changeSet;
else {
    $this->_entityChangeSets[$oid] = $changeSet;

Here is my test case :

$qb = new \Doctrine\ORM\QueryBuilder($em);
            ->from('Entity\FNA', 'fna')
            ->andwhere($qb->expr()->eq('fna.id', ':fna_id'));
$qb->setParameter('fna_id', 1);
$query = $qb->getQuery();

$fna = $query->getSingleResult();


AND The preUdate :

 * @PreUpdate
public function onPreUpdate($args=false)
        $this->modified_at = new \DateTime();

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.


Comment created by romanb:

Fixed now.

Thanks Nico for reporting and thanks Eric for the suggestion!


Issue was closed with resolution "Fixed"

@doctrinebot doctrinebot added this to the 2.0-ALPHA4 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment