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

问题描述 投票:0回答:1

我正在尝试在 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();
    }
}

但是我的新日志没有持久化...... 你有什么解决办法吗?

问候

php symfony events listener
1个回答
1
投票

您使用了错误的侦听器来实现您想要做的事情。引用 PostFlush 事件的 Doctrine documentation

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) 的额外调用。

© www.soinside.com 2019 - 2024. All rights reserved.