尝试在preUpdate中保留另一个实体

时间:2018-09-21 14:55:12

标签: symfony events listener

我正在尝试将另一个实体保留在preUpdate事件侦听器中,但是不起作用...

这是我的代码:

public function preUpdate(LifecycleEventArgs $args) {
    $entity        = $args->getEntity();
    $em = $args->getEntityManager();
    $uow           = $em->getUnitOfWork();
    $session       = new Session();
    $newLog = new Log();
    $newLog->setDate(new DateTime());

    if(!empty($this->toBePersisted))
    {
       array_push($toBePersisted, $historique);
    }
    else
    {
       $toBePersisted[0] = $historique;
    }
}


    public function postFlush(PostFlushEventArgs $event)
{
    if(!empty($this->toBePersisted)) {

        $em = $event->getEntityManager();

        foreach ($this->toBePersisted as $element) {

            $em->persist($element);
        }

        $this->toBePersisted = [];
        $em->flush();
    }
}

但是我的新日志未持久保存... 有什么解决办法吗?

致谢

1 个答案:

答案 0 :(得分:1)

您使用了错误的侦听器来实现您想要的操作。从教义documentation引用postFlush事件:

  

postFlush在EntityManager#flush()的末尾被调用。 EntityManager#flush()无法在其侦听器内部安全地调用。

实现所需功能的正确方法是在onFlush事件中,该事件是功能更强大的准则事件,而不是生命周期回调。因此,您必须在services.yaml中正确设置侦听器:

App\EventListener\LogListener:
    tags:
        - { name: doctrine.event_listener, event: onFlush }

,然后在onFlush事件中

class LogListener {

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

    foreach ($uow->getScheduledEntityUpdates() as $entity) {
        if (!$entity instanceof YourUpdatedEntity) {
            return;
        }

        $newLog = new Log();
        $newLog->setDate(new DateTime());
        $em->persist($newLog);
        $classMetadata = $em->getClassMetadata(Log::class);
        $uow->computeChangeSet($classMetadata, $newLog);
    }
}

}

computeChangeSet函数调用是必需的,因为如onFlush事件的文档中所述:

  

如果您在onFlush中创建并保留新实体,则仅调用EntityManager#persist()是不够的。您必须执行对$ unitOfWork-> computeChangeSet($ classMetadata,$ entity)的附加调用。