为了处理应用程序中一些最后的严重错误,我在两个事件上设置了一个 Doctrine 侦听器:prePersist
和 preRemove
。发生错误时...
- 。在持久保存实体时,会将其删除。
- 。删除实体时,会将其保留回来。
这些操作通过以下方式执行...
$args->getEntityManager()->remove($args->getEntity());
$args->getEntityManager()->persist($args->getEntity());
。分别。但是,如果 prePersist
和 preRemove
都检测到错误,则会创建一个事件循环:
- 实体持久化:触发
prePersist
。 - 调用
remove()
的prePersist
中发生错误。 - 实体被删除:触发
preRemove
。 - 调用
persist()
的preRemove
中发生错误。 - 回到 1.
为了避免这种情况,我想取消对我的实体的任何进一步事件处理。在这种情况下:当第一次触发prePersist
时,它应该以某种方式标记实体,以便它独立于事件链。如果可能,我想避免向我的实体添加字段。
有什么方法可以实现这样的事情吗?或者,也许我应该首先找到另一种方法来取消持久性或删除?
您可以将代码更改为使用事件订阅服务器,而不是事件侦听器,然后可以轻松跟踪任何有错误的对象。
这里有一些伪代码来理解这个想法:
class EventSubscriber implements EventSubscriber
{
private $hasErrors = [];
public function getSubscribedEvents()
{
return array(
Events::prePersist,
Events::preRemove,
);
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = ...
if ($error) {
if (isset($this->hasErrors[$entity->getId()])) {
return; // don't remove entity
}
$this->hasErrors[$entity->getId()] = true;
$this->getEntityManager()->remove($entity);
}
}
public function preRemove(LifecycleEventArgs $args)
{
$entity = ...
if ($error) {
if (isset($this->hasErrors[$entity->getId()])) {
return; // don't persist entity
}
$this->hasErrors[$entity->getId()] = true;
$this->getEntityManager()->persist($entity);
}
}
}