【发布时间】:2015-10-22 13:34:42
【问题描述】:
我的依赖注入遇到了一些问题。我正在尝试在我的 preFlush 侦听器中将记录保存到数据库中。我通过我自己的服务(自定义日志服务)将此记录保存到数据库中。我已经尝试了几种方法,但都没有奏效,我已经尝试了我发现的每一个 google / stackover flow 结果,但恐怕还没有运气。
这是我的记录器类的设置,所有私有变量都已被省略但已设置(我使用请求堆栈和类中其他位置的翻译器,不确定我是否应该省略这个问题):
配置:
core.logger:
class: xxx\CoreBundle\Logger
arguments: [@request_stack, @doctrine.orm.entity_manager, @translator]
类:
public function __construct(RequestStack $requestStack, EntityManager $em, TranslatorInterface $t)
{
$this->requestStack = $requestStack;
$this->em = $em
$this->t = $t;
}
public function addLogEntityChange($uow, $entity) {
$changeset = $uow->getEntityChangeSet($entity);
foreach($changeset as $key => $value) {
$logEntity = new Log();
//setStuff..
$this->em->persist($logEntity);
}
$this->em->flush();
}
这是我的接口代码
配置:
xxxcore.loggerlistener:
class: xxx\CoreBundle\Listener\LoggerListener
calls:
- [ setLogger, [@core.logger] ]
tags:
- { name: doctrine.event_listener, event: preFlush }
界面:
public function setLogger($logger)
{
$this->l = $logger;
}
public function preFlush(PreFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
$uow->computeChangeSets();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
if($entity instanceof LoggerInterface) {
$this->l->addLogEntityChange($uow, $entity);
}
}
}
这导致了
Circular reference detected for service "doctrine.dbal.xxx_connection", path: "doctrine.dbal.xxx_connection".
我尝试在记录器类中手动设置实体管理器,因此删除了依赖注入并使用了 setEntityManager 函数,但这只是页面超时。我试过插入 service_container 但这也没有真正的帮助。
在我持久化实体后手动调用函数时,一切正常,但我想通过带有 preFlush 侦听器的接口自动执行此操作。
任何帮助/见解将不胜感激!
【问题讨论】:
-
教义事件可能很棘手。我认为您的记录器调用 flush 的事实再次启动了 onFlush 并导致了循环。考虑制作第二个实体管理器仅用于日志记录。 symfony.com/doc/current/cookbook/doctrine/…。不确定这是否能解决问题。
-
我的日志实体没有实现 LoggerInterface 所以它没有监听器,即使它有一个检查它不能通过 "if($entity instanceof LoggerInterface) ”。至少应该是这样的,对吧?
-
不。事件由事件管理器触发,而不是由单个实体触发。每次调用 EntityManager::flush 时都会调用 LoggerListener::preFlush。这意味着每个可记录的实体都会一遍又一遍地被记录。因此需要一个 LoggerEntityManager。
-
由于您是从 preFlush 事件中调用它,也许您不需要在您的记录器服务中调用刷新,刷新已经在处理中
-
Entity Log 没有实现 LoggerInterface,所以它不能(或者不应该)通过 preFlush 方法中的检查,所以没有递归。
标签: php symfony circular-reference