【问题标题】:Entity subscriber not called when entity is created within another entity subscriber在另一个实体订阅者中创建实体时未调用实体订阅者
【发布时间】:2017-05-26 13:13:09
【问题描述】:

我有以下情况:

  • 用户创建Scan
  • ScanSubscriber 监听prePersistpreUpdateonFlush
  • onFlush 中,可能会发生一些需要完成与给定Scan 相关的CampaignParticipation 的罕见情况。我在这里更新了一些其他实体,并为相关用户创建了一个AccountBalanceChange。之后我就打电话给$unitOfWork->computeChangeSets();

到目前为止,这工作得很好。现在的问题:

  • 我还有另一个AccountBalanceChangeSubscriber 可以收听postPersist。所以我希望当我持久化我在ScanSubscriber 中创建的AccountBalanceChange 时会调用此订阅者,但这不会发生。

我也尝试过:

$cmf   = $entityManager->getMetadataFactory();
$meta  = $cmf->getMetadataFor(get_class($accountBalanceChange));
$unitOfWork->computeChangeSet($meta, $accountBalanceChange);

所以我的问题是:

  • 我的预期是否应该调用此侦听器,或者“堆叠侦听器”是否存在某种限制?
  • 或者我是否遗漏了一些“注册”以使框架了解新实体,而不管该实体是否正确保存在我的数据库中?

当我使用奏鸣曲管理员保存AccountBalanceChange 时,AccountBalanceChangeSubscriber 本身就像一个魅力。

我的代码(非常短):

ScanSubscriber.php:

class ScanSubscriber implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(
            'onFlush',
        );
    }

    public function onFlush(OnFlushEventArgs $args)
    {
        $entityManager = $args->getEntityManager();
        $unitOfWork = $entityManager->getUnitOfWork();

        foreach ($unitOfWork->getScheduledEntityUpdates() as $entity) {
            if ($entity instanceof Scan) {
                $accountBalanceChange = new AccountBalanceChange();

                $entityManager->persist($accountBalanceChange);
            }
        }

        $unitOfWork->computeChangeSets();
    }
}

AccountBalanceChangeSubscriber.php:

class AccountBalanceChangeSubscriber implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(
            'postPersist',
        );
    }

    public function postPersist(LifecycleEventArgs $args)
    {
        // This is never called in the case I described but works when I save the entity using sonata admin
    }
}

【问题讨论】:

  • 我只是在分析您的代码时查看github.com/Atlantic18/DoctrineExtensions/blob/v2.4.x/lib/Gedmo/…。由于操作非常相似。你有没有试过在persist后显式调用$unitOfWork->computeChangeSet($entityManager->getClassMetadata($accountBalanceChange), $accountBalanceChange)
  • 不确定是否是问题所在,但 postPersist 仅在实际 INSERT 发生后运行(here'sUnitOfWork::executeInserts 中的相关代码)
  • 理论监听器有无数的限制,尤其是在尝试更改实体时。基本上,您正在尝试在持久层操作期间执行业务逻辑。可能想看看您是否可以在 Doctrine 之外完全实现所需的功能。

标签: php symfony doctrine-orm symfony-3.2


【解决方案1】:

最后我决定重构我的代码,将逻辑从“第二个”侦听器移到一个单独的命令中。就在我完成此操作时,我发现了一个非常复杂的“功能”链,导致我认为订阅者没有被调用。实际上它被调用并且一切都按我在我的问题中的预期工作但是还有另一个UserSubscriber 不允许标记Users 的几乎所有属性更改作为anonymous(在我的情况下,直到他们“声称”他们的帐户)。而且我忘记将我想在AccountBalanceChange 中更改的两个属性列入白名单。

所以,感谢 cmets 以正确的方式指导我,祝你周末愉快! :-)

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    相关资源
    最近更新 更多