How can I tell if the current transaction will change any entities with Doctrine 2?

doctrine-orm, mysql, php

Solution

This is a necessary reply that aims at correcting what @ColinMorelli posted (since flushing within an lifecycle event listener is disallowed - yes, there's one location in the docs that says otherwise, but we'll get rid of that, so please don't do it!).

You can simply listen to `onFlush` with a listener like following:

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Events;

class UpdateUserEventSubscriber implements EventSubscriber
{
    protected $user;

    public function __construct(User $user)
    {
        // assuming the user is managed here
        $this->user = $user;
    }

    public function onFlush(OnFlushEventArgs $args)
    {
        $em  = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        // before you ask, `(bool) array()` with empty array is `false`
        if (
            $uow->getScheduledEntityInsertions()
            || $uow->getScheduledEntityUpdates()
            || $uow->getScheduledEntityDeletions()
            || $uow->getScheduledCollectionUpdates()
            || $uow->getScheduledCollectionDeletions()
        ) {
            // update the user here
            $this->user->setLastModifiedDate(new DateTime());
            $uow->recomputeSingleEntityChangeSet(
                $em->getClassMetadata(get_class($this->user)), 
                $this->user
            );
        }
    }

    public function getSubscribedEvents()
    {
        return array(Events::onFlush);
    }
}

This will apply the change to the configured `User` object only if the `UnitOfWork` contains changes to be committed to the DB (an unit of work is actually what you could probably define as an application level state transaction).

You can register this subscriber with the ORM at any time by calling

$user         = $entityManager->find('User', 123);
$eventManager = $entityManager->getEventManager();
$subscriber   = new UpdateUserEventSubscriber($user);

$eventManager->addEventSubscriber($subscriber);

Problem

I'm using Doctrine to save user data and I want to have a `last modification` field. Here is the pseudo-code for how I would like to save the form once the user presses `Save`: - start transaction - do a lot of things, possibly querying the database, possibly not - if anything will be changed by this transaction - modify a `last updated` field - commit transaction The problematic part is `if anything will be changed by this transaction`. Can Doctrine give me such information? How can I tell if entities have changed in the current transaction? edit Just to clear things up, I'm trying to modify a field called `lastUpdated` in an entity called `User` if any entity (including but not limited to `User`) will be changed once the currect transaction is commited. In other words, if I start a transaction and modify the field called `nbCars` of an entity called `Garage`, I wish to update the `lastUpdated` field of the `User` entity even though that entity hasn't been modified.

Original source

Related problems