后波斯特;Symfony中的后刷新无限循环
我试图在用户进入数据库后将咖啡配置文件链接到用户。 此咖啡配置文件数据位于会话中,我正在postFlush中使用此会话 然而,这段代码正在创建一个无限循环,我不知道为什么: UserListener.php:后波斯特;Symfony中的后刷新无限循环,symfony,doctrine,flush,persist,Symfony,Doctrine,Flush,Persist,我试图在用户进入数据库后将咖啡配置文件链接到用户。 此咖啡配置文件数据位于会话中,我正在postFlush中使用此会话 然而,这段代码正在创建一个无限循环,我不知道为什么: UserListener.php: <?php namespace AppBundle\EventListener; use FOS\UserBundle\FOSUserEvents; use FOS\UserBundle\Event\FormEvent; use Symfony\Component\HttpFou
<?php
namespace AppBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use AppBundle\Entity\Consumption;
use AppBundle\Entity\CoffeeOption;
use AppBundle\Entity\Consumeable;
use AppBundle\Entity\MomentPreference;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\PostFlushEventArgs;
class UserListener
{
private $container;
private $user;
public function __construct(ContainerInterface $container = null)
{
$this->container = $container;
}
public function postPersist(LifecycleEventArgs $args)
{
$user = $args->getEntity();
$this->user = $user;
}
public function postFlush(PostFlushEventArgs $args)
{
$session = new Session();
if($session) {
$em = $args->getEntityManager();
$us = $em->getRepository('AppBundle:User')->findOneById($this->user->getId());
$consumption = $session->get('consumption');
$coffee = $session->get('coffee');
$moment = $session->get('moment');
$consumption->setUser($us);
//dummy data for the day, later this needs to be turned into datetime
$moment->setDay('monday');
$moment->setConsumption($consumption);
$em->persist($consumption);
$em->persist($coffee);
$em->persist($moment);
$em->flush();
} else {
return $this->redirectToRoute('fos_user_registration_register');
}
}
}
是什么导致了此循环以及如何修复它?您正在postPersist事件中调用
$em->flush()
,其中声明:
在EntityManager#flush()的末尾调用postFlush。
无法在其侦听器中安全地调用EntityManager#flush()
您应该使用其他事件,如prePersist
或postersist
如果可能的话,尽量避免对单个请求执行多个flush()
顺便说一下,没有必要这样做,因为您的用户对象已经包含在$user变量中
美元=
$em->getRepository('AppBundle:User')->findOneById($this->User->getId())
您正在postPersist事件中调用
$em->flush()
,声明如下:
在EntityManager#flush()的末尾调用postFlush。
无法在其侦听器中安全地调用EntityManager#flush()
您应该使用其他事件,如prePersist
或postersist
如果可能的话,尽量避免对单个请求执行多个flush()
顺便说一下,没有必要这样做,因为您的用户对象已经包含在$user变量中
美元=
$em->getRepository('AppBundle:User')->findOneById($this->User->getId())
在
postFlush
事件中,您再次刷新。这就是导致无限循环的原因,因为每次调用flush
方法时都会触发postfush
事件
我不确定您想要实现什么,但您的目标是每次保存用户时创建一个咖啡消费量,您可以在方法的开头添加这样的测试:
$entity = $args->getObject();
if (!$entity instanceof User) {
return;
}
这将防止无限循环
还有几件事:
- 您的
方法似乎没有用。每次对象被持久化时都会调用它,因此您的postPersist
属性不一定是用户对象$this->user
- 如果需要用户,则不必在数据库中获取它。只需使用
获取刷新的实体。除了上面的测试之外,您将确保该方法将返回一个用户对象$args->getObject()
- 这不是检查用户是否登录到您的Doctrine侦听器的很好实践。这不是我们班应该做的
- 不要将容器注入构造函数中。只注射你需要的(在这种情况下……什么都不注射?)
postFlush
事件中,您再次刷新。这就是导致无限循环的原因,因为每次调用flush
方法时都会触发postfush
事件
我不确定您想要实现什么,但您的目标是每次保存用户时创建一个咖啡消费量,您可以在方法的开头添加这样的测试:
$entity = $args->getObject();
if (!$entity instanceof User) {
return;
}
这将防止无限循环
还有几件事:
- 您的
方法似乎没有用。每次对象被持久化时都会调用它,因此您的postPersist
属性不一定是用户对象$this->user
- 如果需要用户,则不必在数据库中获取它。只需使用
获取刷新的实体。除了上面的测试之外,您将确保该方法将返回一个用户对象$args->getObject()
- 这不是检查用户是否登录到您的Doctrine侦听器的很好实践。这不是我们班应该做的
- 不要将容器注入构造函数中。只注射你需要的(在这种情况下……什么都不注射?)
flush
方法,但是如果你不想要无限循环,就不能在用户实体上使用它。我已经将它改为postUpdate,现在它就像一个符咒一样工作!非常感谢你!我为这个问题绞尽脑汁已经有一段时间了!Postflush使用PostFlusheEventArgs而不是LifecycleEventArgs。PostFlushEventArgs中没有用户对象。我的postpersist案例是否应该使用postflush?当我不能使用flush()时,如何刷新需要链接到用户的咖啡配置文件?@MarcoKoopman很好。您应该使用postUpdate。你可以在你的事件中使用flush
方法,但是如果你不想要无限循环,就不能在用户实体上使用它。我已经将它改为postUpdate,现在它就像一个符咒一样工作!非常感谢你!我为这个问题绞尽脑汁已经有一段时间了!如果我在postPersist中不使用flush(),它不会将咖啡配置文件推送到数据库。但是如果我在postPersist中使用flush(),我会得到一个错误。如果我在postPersist中不使用flush(),它不会将咖啡配置文件推送到数据库。但是如果我在postPersist中使用flush(),我会得到一个错误。。