symfony – 使用Doctrine的PreUpdate生命周期事件保留对文档所做的更改

我有一个包含两个生命周期事件方法的事件订阅者:prePersist和preUpdate. prePersist正在按预期工作 – 我修改了文档,稍后在检索文档时会反映这些更改.但是,preUpdate没有按预期工作.这基本上是它的样子:

/**
 * Also update the foo code when the bar profile is updated.
 * @param LifecycleEventArgs $args
 */
public function preUpdate(LifecycleEventArgs $args)
{
    $document = $args->getDocument();
    if ($document instanceof BarProfile) {
        $document->setFooCode('Salamanders');
    }
}

如果我创建一个文档并将其fooCode设置为perPersist函数中的’placeholder’,那么当我稍后检索文档时,fooCode就是’占位符’.如果我然后更新它,并再次检索它,那么我希望它的fooCode是’Salamanders’.但是,它仍然是“占位符”.我甚至尝试将error_log()内容放在那里并将内容写入日志,这样我就可以看到正在执行此方法.

在$document-> setFooCode()之后我需要做的第二步是使fooCode的新值保持不变吗?

最佳答案 您无法直接在preUpdate事件中修改字段,您必须修改其原始值.不允许对关联进行更改.你必须这样做:

$eventArgs->setNewValue('fooCode', 'Salamanders');

您声明“prePersist正在按预期工作 – 我修改了文档,稍后在检索文档时会反映这些更改.”

这让我相信你可能没有意识到持久性和更新之间的区别.在Doctrine中,第一次创建对象时会出现持久性.当您对已由Doctrine管理的现有对象进行更改时,会发生更新.很多人对此感到困惑,但是在更新现有实体时不需要调用persist(),只需调用flush()即可.例如:

// inserts a new entity into the database
$document = new Document();
$document->setName('My Document');

$em->persist($document);
$em->flush();

// retrieves entity from the database, makes a change, then updates the database
$document = $em->findOneByName('My Document');
$document->setFooCode('Salamanders');

$em->flush();

我鼓励你像杰拉德建议的read the Doctrine documentation.请密切关注preUpdate事件的以下语句:

  • PreUpdate is the most restrictive to use event
  • Changes to associations of the updated entity are never allowed in this event
  • Changes to fields of the passed entities are not recognized by the flush operation anymore, use the computed change-set passed to the event to modify primitive field values
点赞