我有一个包含两个生命周期事件方法的事件订阅者: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