如果实体被写入DB(postFlush),使用哪个事件来获得通知



我在Symfony4项目中有一个(条令(实体。我要找的是类似postFlush事件的东西(例如之后的,它已被写入DB(。

我想通知其他系统,如果更新了Customer,我可以向队列发送CustomerUpdated($customer->id)消息。我很难找到合适的侦听器/事件处理程序。当前的问题是,事件是在DB写入之前调度的,因此消费服务会询问尚未存在的条目的信息(大约2秒(,或者在DB尚未更新时获取旧数据。

我尝试过的:

  • class CustomerListener implements EntityListener {
    public function getSubscribedEvents(): array {
    return [ Events::postFlush ];
    }
    public function postFlush(){ die('looking for me?'); }
    }
    
    这完全没有任何作用,而且悄无声息地失败了
  • 我还使用了Events::postUpdate事件,它对新条目不起作用(数据还没有刷新到数据库中,导致了旧数据(
  • 我还为新项目使用Events::postPersist事件,这不起作用,因为数据库中还不存在数据!(这是我目前面临的挑战(
  • Doctrine医生也没有告诉我任何有用的东西(或者我没有看到(
  • 当然,我试过研究这个,但似乎什么都找不到

我要查找的内容:

  1. 创建实体或更新实体
  2. 实体写入数据库
  3. 现在在这里做点什么。我不想再更改实体,只需在保存后通知其他系统即可

postPersist和PostUpdate都在点1&2,并且不合适。我知道flush不是特定于实体的,但我需要一些东西
可能是我使用的侦听器/eventSubscriber不正确,此时I;I’我在森林里寻找树木。

我很难找到答案,所以我自己回答:

实体级别上没有"postFlush"事件。只有一个全局实体,例如,您可以获得正在刷新的EVERYTHING,用于创建、更新和删除语句的所有实体。

我制作了一个EntityFlushListener,并将其剥离为M.V.p.,例如:

/**
* This class listens to flush events in order to dispatch they're respective messages unto the queue.
* There is no specific 'postFlush' event for an entity, so this is a global listener for ALL entities.
*/
class EntityFlushListener implements EventSubscriber
{
private UnitOfWork $uow;
private array $storedInserts = [];
private array $storedUpdates = [];
private array $storedDeletes = [];
public function __construct(EntityManagerInterface $entityManager) {
$this->uow = $entityManager->getUnitOfWork();
}
public function getSubscribedEvents(): array
{
return [Events::onFlush, Events::postFlush];
}
/*
* We have to use the 'onFlush' event to get the entities to dispatch AFTER the flush, as 'postFlush' is unaware
* Please note: duplicates will occur. Logic to fix this might need to be implemented
*/
public function onFlush(OnFlushEventArgs $eventArgs): void
{
$this->storedInserts = $this->uow->getScheduledEntityInsertions();
$this->storedUpdates = $this->uow->getScheduledEntityUpdates();
$this->storedDeletes = $this->uow->getScheduledEntityDeletions();
}
/*
* It has now been written in the DB, do what you want with it
*/
public function postFlush(PostFlushEventArgs $eventArgs): void
{
dd(
$this->storedInserts,
$this->storedUpdates,
$this->storedDeletes,
);
}
}

最新更新