Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recomputing entity changeset in onFlush listener

Consider the following schema:

[Work]
id
tags ManyToMany(targetEntity="Tag", inversedBy="works", cascade={"persist"})

[Tag]
id
works_count
works ManyToMany(targetEntity="Work", mappedBy="tags")

works_count is a counter cache for Tag::works.

I have a onFlush listener on Work that checks if Work::tags has changed, and updates each of the tags' works_count.

public function onFlush(OnFlushEventArgs $args)
{
    foreach ($uow->getScheduledEntityUpdates() as $work) {
        $changedTags = /* update relevant tags and return all the changed ones */

        $metadata = $em->getClassMetadata('Acme\Entity\Tag');

        foreach ($changedTags as $tag) {
            $uow->recomputeSingleEntityChangeSet($metadata, $tag);
        }
    }
}

Now if I read the changesets of the updated tags, the changes of works_count appears correctly, but they don't get updated in the database..

If I replace recomputeSingleEntityChangeSet() with computeChangeSet() then everything works as expected and the DB is updated, but computeChangeSet() has an @internal Don't call from the outside. annotation on it, so I'm not sure what the consequences are..

Every source on the internet says to use recomputeSingleEntityChangeSet so why doesn't it work in this case?

P.S The tags are managed by the EntityManager ($em->contains($tag) returns true)

like image 380
tamir Avatar asked May 16 '13 21:05

tamir


2 Answers

It seems that Doctrine 2.2 can merge change sets or generate new change sets, but it needs to know which. If you get it wrong, it will either replace your existing change sets or do nothing at all. I'd be very interested to know if there is a better option than this, or if this is even right.

    if($uow->getEntityChangeSet($entity)) {
        /** If the entity has pending changes, we need to recompute/merge. */
        $uow->recomputeSingleEntityChangeSet($meta, $contact);
    } else {
        /** If there are no changes, we compute from scratch? */
        $uow->computeChangeSet($meta, $entity);
    }
like image 23
Ryan Avatar answered Sep 25 '22 07:09

Ryan


This problem was related with a bug in UnitOfWork and finally it's fixed with the release of Doctrine ORM 2.4.3 on September 11, 2014. See DDC-2996 for details.

like image 92
edigu Avatar answered Sep 22 '22 07:09

edigu