我正在尝试在 preUpdate 事件侦听器中保留另一个实体,但它不起作用...
这是我的代码:
public function preUpdate(LifecycleEventArgs $args) {
$entity = $args->getEntity();
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
$session = new Session();
$newLog = new Log();
$newLog->setDate(new DateTime());
if(!empty($this->toBePersisted))
{
array_push($toBePersisted, $historique);
}
else
{
$toBePersisted[0] = $historique;
}
}
public function postFlush(PostFlushEventArgs $event)
{
if(!empty($this->toBePersisted)) {
$em = $event->getEntityManager();
foreach ($this->toBePersisted as $element) {
$em->persist($element);
}
$this->toBePersisted = [];
$em->flush();
}
}
但是我的新日志没有持久化...... 你有什么解决办法吗?
问候
您使用了错误的侦听器来实现您想要做的事情。引用 PostFlush 事件的 Doctrine documentation:
postFlush 在 EntityManager#flush() 结束时调用。 EntityManager#flush() 无法在其侦听器内安全地调用。
实现您想要的内容的正确方法是在 onFlush 事件内部,这是更强大的学说事件,但不是生命周期回调。因此,您必须在 services.yaml 中正确设置监听器:
App\EventListener\LogListener:
tags:
- { name: doctrine.event_listener, event: onFlush }
然后在 onFlush 事件中:
class LogListener {
public function onFlush(OnFlushEventArgs $args) {
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
if (!$entity instanceof YourUpdatedEntity) {
return;
}
$newLog = new Log();
$newLog->setDate(new DateTime());
$em->persist($newLog);
$classMetadata = $em->getClassMetadata(Log::class);
$uow->computeChangeSet($classMetadata, $newLog);
}
}
}
需要调用computeChangeSet函数,因为如onFlush事件的文档中所述:
如果您在 onFlush 中创建并持久化一个新实体,那么调用 EntityManager#persist() 是不够的。您必须执行对 $unitOfWork->computeChangeSet($classMetadata, $entity) 的额外调用。