【问题标题】:Symfony2 - Doctrine - no changeset in post updateSymfony2 - 教义 - 更新后没有变更集
【发布时间】:2016-02-22 13:12:21
【问题描述】:

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

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 中看到。谁能看到我做错了什么?帮助将不胜感激:)

【问题讨论】:

  • 我认为在 PostUpdate 事件 Doctrine 中没有遵循任何更改 - 并且更改集将为空。您需要在 preupdate 中获取变更集并从这里处理它。
  • 好的,谢谢,我确定我已经在 postUpdate 中获得了变更集,这让我很困惑

标签: php symfony doctrine


【解决方案1】:

preUpdate 事件上,您将获得PreUpdateEventArgs 类的事件对象,其中您已为实体设置了更改。

postUpdate 上,您只需获得LifecycleEventArgs 类的事件对象,您只能在其中询问更新的实体(并获取它的最新状态)。

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

【讨论】:

  • 感谢您的回复,我设法找到了我以前从事的 symfony2 项目,并且可以使用以下行 $changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($entity); 访问更新后的变更集。但是目前我正在运行的项目中的完全相同的行不起作用。我想这一定是某个地方的不同问题
  • 谢谢!将 postUpdate 更改为 preUpdate 对我有用(我从另一个配置复制粘贴但忘记更改)
【解决方案2】:

一种解决方法是您自己将更改集保存在某处,然后在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,
        ];
    }
}

稍后在 postUpdate 事件上需要的侦听器中注入 ChangeSetStorage 服务。

【讨论】:

    【解决方案3】:

    我在变更集数据方面遇到了一个非常烦人的问题,有时我得到了变更集合,有时却没有。

    我通过在 prePersistpreUpdate 中添加这一行 $event->getEntityManager()->refresh($entity); 进行整理> doctrine.event_subscriber

    中的事件

    在刷新行之后,changesetdata 已更新,因此以下行开始工作:

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

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 2014-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-14
      • 2013-05-26
      相关资源
      最近更新 更多