未调用EntityListener preUpdate prePersist

时间:2019-04-30 10:49:30

标签: symfony doctrine-orm doctrine

我经常使用主义的事件监听器,但这是我的第一个实体监听器。

class ReportListener
{
    /** @ORM\PreUpdate */
    public function preUpdate(Report $report, PreUpdateEventArgs $args)
    {
        $report->updatedAt = new \DateTime();
        $this->logger->debug('UpdatedAt ' . $report->updatedAt->format('c')); // I get *NO* log !!!

        $this->entityManager->getUnitOfWork()->recomputeSingleEntityChangeSet(
            $this->entityManager->getClassMetadata(Report::class), $report); // is this necessary?
    }

    public function prePersist(Report $report, LifecycleEventArgs $args)
    {
        $report->updatedAt = new \DateTime();
        $this->logger->debug('UpdatedAt ' . $report->updatedAt->format('c')); // not called!
        $this->entityManager->getUnitOfWork()->recomputeSingleEntityChangeSet(
            $this->entityManager->getClassMetadata(Report::class), $report); // do I need that?
    }

    public function postUpdate(Report $report, LifecycleEventArgs $args)
    {
        // IS CALLED !!!!
    }

    public function postPersist(Report $report, LifecycleEventArgs $args)
    {
        // IS CALLED !!!
    }
}

因此,它应该只更新updatedAt时间戳... 我的实体是标准的:

@ORM\Table(name="report")
 * @ORM\Entity()
 * @ORM\EntityListeners({"App\EventListener\ReportListener"})
 */
class Report {...}

我在symfony上下文中使用它,我什至显式注册了每个事件,但是没有运气。

report_listener:
    class: App\EventListener\ReportListener
    tags:
        - { name: doctrine.orm.entity_listener, event: preUpdate}
        - { name: doctrine.orm.entity_listener, event: prePersist}
        - { name: doctrine.orm.entity_listener, event: postUpdate}
        - { name: doctrine.orm.entity_listener, event: postPersist}

另一个问题是我是否真的需要重新计算在PrePersist和preUpdate中设置的更改...

2 个答案:

答案 0 :(得分:0)

首先,因为您没有在prePersist / preUpdate之前更新实体,所以不需要重新计算它。

第二,您不需要为服务侦听器添加注释。请阅读此文档以获取更多信息。我认为您应该做什么很清楚:https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html#listening-and-subscribing-to-lifecycle-events

答案 1 :(得分:0)

最近我遇到了这样的问题,在实现了一个新的实体侦听器之后,我的 symfony 2 应用程序不会调用它,这让我烦恼了大约一个小时左右,并且在实现之后首先要清除学说元数据实体侦听器的更改,即使在我的开发环境中也是如此。

app/console doctrine:cache:clear-metadata

在我的开发环境中,我必须清除元数据,即使在实现了一个新函数之后,该函数在现有的实体侦听器类中并不存在。 根据我的经验,当函数使用默认名称(如 postLoad - preFlush - preUpdate - postUpdate 等)时,实体侦听器类中不需要注释。如果实体侦听器类需要加载某些服务,则像下面这样的服务声明就足够了。

    app.entity_listener.check_cif_changes:
    class: App\MainBundle\EventListener\CheckForCifChangesListener
    arguments:
        - '@services.send_mail_helper'
    tags:
        - {name: doctrine.orm.entity_listener, lazy: true}

我还记录了一些有关实体侦听器的更多信息:

  • 实体创建的事件顺序:prePersist - preFlush - postPersist
  • 实体更新的事件顺序:postLoad - preFlush - preUpdate - postUpdate
  • 可以安全使用刷新的事件:postPersist - postUpdate

symfony 3+ 中清除元数据命令的变化

bin\console doctrine:cache:clear-metadata