Symfony2 - Doctrine - 更新后没有变更集

时间:2016-02-22 13:12:21

标签: php symfony doctrine

所以当我更改某个实体的某个值时,我会发送一封电子邮件。我只希望在更新后发送电子邮件以防更新因任何原因而失败。所以在preUpdate上我可以做到这一点

public function preUpdate(LifecycleEventArgs $args){

    if ($args->hasChangedField('value') && is_null($args->getOldValue('value'))) {
        $this->sendEmail();
    }

}

但我需要在postUpdate上执行此操作,因为这些方法在postUpdate上不可用,我重构它看起来像这样:

public function postUpdate(LifecycleEventArgs $args){

    $entity      = $args->getEntity();
    $changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($entity);

    if ($entity  instanceof Entity && isset( $changeSet['value'] ) && empty( $changeSet['value'][0] )) {
        $this->sendEmail();
    }
}

但是,这会返回一个空的更改集,但是已经进行了更改,并且可以在preUpdate中看到。谁能看到我做错了什么?帮助将非常感谢:)

3 个答案:

答案 0 :(得分:3)

preUpdate事件中,您将获得类PreUpdateEventArgs的事件对象,其中您具有实体的更改集。

postUpdate上,您只需获取类LifecycleEventArgs的事件对象,您可以只询问已更新的实体(并获取其最新状态)。

如果您想使用变更集,则需要在实际更新实体(preUpdate事件)之前执行此操作。

答案 1 :(得分:1)

解决方法可能是自行保存更改集,然后在postUpdate中检索它。这是我曾经实施过的一个简单的例子:

<?php

namespace Awesome\AppBundle\EventListener;

use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;

/**
 * Store last entity change set in memory, so that it could be
 * usable in postUpdate event.
 */
class EntityChangeSetStorageListener implements EventSubscriber
{
    /**
     * @var ArrayCache
     */
    private $cache;

    /**
     * @param ArrayCache $cacheStorage
     */
    public function __construct(ArrayCache $cacheStorage)
    {
        $this->cache = $cacheStorage;
    }

    /**
     * Store last entity change set in memory.
     *
     * @param PreUpdateEventArgs $event
     */
    public function preUpdate(PreUpdateEventArgs $event)
    {
        $entity = $event->getEntity();

        $this->cache->setNamespace(get_class($entity));
        $this->cache->save($entity->getId(), $event->getEntityChangeSet());
    }

    /**
     * Release the memory.
     */
    public function onClear()
    {
        $this->clearCache();
    }

    /**
     * Clear cache.
     */
    private function clearCache()
    {
        $this->cache->flushAll();
    }

    /**
     * {@inheritdoc}
     */
    public function getSubscribedEvents()
    {
        return [
            Events::preUpdate,
            Events::onClear,
        ];
    }
}

稍后将ChangeSetStorage服务注入到postUpdate事件所需的侦听器。

答案 2 :(得分:0)

我对变更集数据有一个非常恼人的问题,有时我得到了变更集合,有时却没有。

我通过在 prePersist preUpdate <中添加此行 $ event-&gt; getEntityManager() - &gt; refresh($ entity); 进行整理/ strong> doctrine.event_subscriber

中的事件

刷新后,更新了setsetdata,以便以下行开始工作:

/** @var array $changeSet */
$changeSet = $this->em->getUnitOfWork()->getEntityChangeSet($entity);