【发布时间】:2017-05-26 13:13:09
【问题描述】:
我有以下情况:
- 用户创建
Scan -
ScanSubscriber监听prePersist、preUpdate和onFlush - 在
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's
UnitOfWork::executeInserts中的相关代码) -
理论监听器有无数的限制,尤其是在尝试更改实体时。基本上,您正在尝试在持久层操作期间执行业务逻辑。可能想看看您是否可以在 Doctrine 之外完全实现所需的功能。
标签: php symfony doctrine-orm symfony-3.2