我正在尝试在用户进入数据库后将咖啡配置文件链接到用户。 这个咖啡个人资料数据在会话中,我在postFlush中使用此会话。
但是这段代码创建了一个无限循环,我不知道为什么:
UserListener.php:
<?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');
}
}
}
Services.yml:
zpadmin.listener.user:
class: AppBundle\EventListener\UserListener
arguments: ['@service_container']
tags:
- { name: doctrine.event_listener, event: postPersist }
- { name: doctrine.event_listener, event: postFlush }
导致此循环的原因是什么?如何解决?
答案 0 :(得分:1)
您在postPersist活动中呼叫$em->flush()
,在docs中声明:
在EntityManager #flush()结束时调用postFlush。 无法在侦听器内安全地调用EntityManager#flush()。
您应该使用其他活动,例如prePersist
或postPersist
。
如果可能,请尝试在单个请求中避免多个flush()
。
$ us = $ EM-&GT; getRepository(&#39;的appbundle:用户&#39;) - &GT; findOneById($这 - &GT;用户&GT;的getId());
答案 1 :(得分:1)
在你的postFlush
事件中,你再次冲了过来。这就是导致无限循环的原因,因为每次调用postFlush
方法时都会触发flush
事件。
我不确定您要实现的目标,但您的目标是每次保存用户时都要创建咖啡消费,您可以在方法开头添加类似这样的测试:
$entity = $args->getObject();
if (!$entity instanceof User) {
return;
}
这将阻止无限循环。
还有一些事情:
postPersist
方法似乎毫无用处。每次持久化对象时都会调用它,因此您的$this->user
角色不一定是用户对象。$args->getObject()
即可获得刷新的实体。除了上面的测试之外,您还可以确定该方法将返回一个User对象。