【发布时间】:2015-08-24 10:25:59
【问题描述】:
为了清楚起见,我继续讨论开始here。
在Doctrine Entity Listener 中,在 preUpdate 方法中(我可以访问实体的任何字段的旧值和新值),我试图保留一个与焦点无关的实体。
基本上我有实体 A,当我在 project_notification 表中更改要写入的字段之一中的值时,字段 oldValue、newValue 以及其他字段。
如果我不在 preUpdate 方法中刷新,则新的通知实体不会存储在 DB 中。如果我刷新它,我会进入一个无限循环。
这是 preUpdate 方法:
public function preUpdate(ProjectTolerances $tolerances, PreUpdateEventArgs $event)
{
if ($event->hasChangedField('riskToleranceFlag')) {
$project = $tolerances->getProject();
$em = $event->getEntityManager();
$notification = new ProjectNotification();
$notification->setValueFrom($event->getOldValue('riskToleranceFlag'));
$notification->setValueTo($event->getNewValue('riskToleranceFlag'));
$notification->setEntity('Entity'); //TODO substitute with the real one
$notification->setField('riskToleranceFlag');
$notification->setProject($project);
$em->persist($notification);
// $em->flush(); // gives infinite loop
}
}
谷歌搜索了一下,我发现你不能在侦听器中调用刷新,here 建议将要持久化的内容存储在数组中,以便稍后在 onFlush 中刷新。尽管如此,它不起作用(并且可能它不应该起作用,因为在您调用 preUpdate 后侦听器类的实例会被破坏,因此当您稍后调用 onFlush 时,无论您存储为类级别的受保护属性的任何内容都会丢失,还是我错过了什么?)。
这是监听器的更新版本:
class ProjectTolerancesListener
{
protected $toBePersisted = [];
public function preUpdate(ProjectTolerances $tolerances, PreUpdateEventArgs $event)
{
$uow = $event->getEntityManager()->getUnitOfWork();
// $hasChanged = false;
if ($event->hasChangedField('riskToleranceFlag')) {
$project = $tolerances->getProject();
$notification = new ProjectNotification();
$notification->setValueFrom($event->getOldValue('riskToleranceFlag'));
$notification->setValueTo($event->getNewValue('riskToleranceFlag'));
$notification->setEntity('Entity'); //TODO substitute with the real one
$notification->setField('riskToleranceFlag');
$notification->setProject($project);
if(!empty($this->toBePersisted))
{
array_push($toBePersisted, $notification);
}
else
{
$toBePersisted[0] = $notification;
}
}
}
public function postFlush(LifecycleEventArgs $event)
{
if(!empty($this->toBePersisted)) {
$em = $event->getEntityManager();
foreach ($this->toBePersisted as $element) {
$em->persist($element);
}
$this->toBePersisted = [];
$em->flush();
}
}
}
也许我可以通过从侦听器内部触发一个事件来解决这个问题,其中包含在刷新后执行我的日志记录操作所需的所有信息......但是:
1) 我不知道我能不能做到
2) 好像有点矫枉过正
谢谢!
【问题讨论】:
标签: symfony doctrine-orm