Doctrine2的preUpdate在Symfony2中缺少PreUpdateEventArgs参数

时间:2012-02-04 12:20:31

标签: php symfony doctrine-orm

关于preUpdate活动says

的Doctrine2文档
  

此事件具有强大的功能,但它使用PreUpdateEventArgs实例执行,该实例包含对此实体的计算更改集的引用。这意味着您可以使用旧值和新值访问已为此实体更改的所有字段。

听起来很有用!所以我做了什么:

/**
 * Acme\TestBundle\Entity\Article
 *
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class Article
{
    // ...

    /**
     * @ORM\PreUpdate
     */
    public function preUpdate(\Doctrine\ORM\Event\PreUpdateEventArgs $eventArgs)
    {
        if ( /* use $eventArgs here */ )

            $this->updatedAt = new \DateTime();
    }

    // ...
}

但没有运气 - 没有传递任何论据:

  

可捕获的致命错误:参数1传递到
  Acme\TestBundle\Entity\Article::preUpdate()必须是
的实例   Doctrine\ORM\Event\PreUpdateEventArgs没有给出,在。中调用   第1540行...\vendor\doctrine\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php并在...\src\Acme\TestBundle\Entity\Article.php第163行

中定义

我想这必须在Symfony2中以其他方式工作。我该怎么做?

2 个答案:

答案 0 :(得分:16)

您应该记住,使用PreUpdateEventArgs实例,您可以访问具有旧实体和新值的此实体已更改的所有字段。但在你的例子中,updatedAt不会在那个变更集上。如果您尝试设置updatedAt值,则应该收到错误:“字段'updated't'不是实体的有效字段”。因此,您可以更改updateAt字段,然后使用UnitOfWork:recomputeSingleEntityChangeSet。例如:

public function preUpdate(PreUpdateEventArgs $args)
{
    $entity = $args->getEntity();
    $em = $args->getEntityManager();
    $uow = $em->getUnitOfWork();

    if ($entity instanceof Product)
    {
        $entity->setDiscount(123);

        $uow->recomputeSingleEntityChangeSet(
            $em->getClassMetadata("XXXBundle:Product"),
            $entity
         );
    }
}

我博客文章中的更多代码示例(关于russain :)):Update doctine entity in preUpdate event

答案 1 :(得分:4)

有两种处理生命周期事件的方法。

首先,只需将您的学说实体的方法注释为@ORM \ PreUpdate。更新前将调用此方法。第二个更复杂。它涉及听众 preUpdate。这是您订阅的独立课程,可以收听特定事件。

再次仔细阅读here和symfony cookbook