它有一个实体和2个事件监听器,当字段更新时,检查器检查该字段是否已更改,然后处理逻辑。问题是侦听器阻塞了第二个侦听器,因此更改检查器在第二个侦听器中不起作用(它说该字段没有更改),尽管基础中有更改。
public function postUpdate(LifecycleEventArgs $eventArgs): void
{
$entity = $eventArgs->getObject();
if ($entity instance of Group) {
$changedFields = $eventArgs->getEntityManager()->getUnitOfWork()->getEntityChangeSet($entity);
$isChanged = $this->checker->isChanged($changedFields, ['teacher']);
if ($isChanged) {
$this->proceedTeacherChanges($entity);
}
当进入 Listener 时,Doctrine 会重新计算所有的变化,即 为您执行 EntityManager->getUnitOfWork->computeChangesSet 操作。这一点很重要,因为 在底层,它覆盖了 originalEntityData 数据数组,在此基础上它基本上进行了所有进一步的检查,如 isChanged 等。
在您的情况下,会发生以下情况:
这正是由于这个 originalEntityData 数据数组而发生的,在重新计算期间它会将其更新为实体的状态,并且在重新计算时,它不会因此而看到变化。
通常文档说您不需要自己重新计算 Listener 中的 changesSet,因为 它是自动计算的,但在您的情况下,事实证明您通过双重订阅强制 Doctrine 将其计算两次(不推荐)。