【问题标题】:How to resolve "Circular reference detected for service" issue?如何解决“检测到服务的循环引用”问题?
【发布时间】:2015-09-08 20:27:40
【问题描述】:

我正在尝试将我的存储库服务注入 EventListener 但这导致我出现以下异常,根据我对 Symfony2 的基本知识,我不知道如何解决。例外是:

bootstrap.php.cache 第 2129 行中的 ServiceCircularReferenceException:

检测到服务“doctrine.orm.default_entity_manager”的循环引用,路径:“doctrine.orm.default_entity_manager -> mess.dbal.default_connection -> person.connect.listener -> tag.repository.service”。

这是我声明存储库和监听器的方式:

tag.repository.service:
    class: Application\Bundle\PersonBundle\Entity\TagRepository
    factory: ["@doctrine", getRepository]
    arguments: [ Application\Bundle\PersonBundle\Entity\Tag ]

person.connect.listener:
    class: Application\Bundle\PersonBundle\EventListener\ConnectListener
    arguments:
        tokenStorage: "@security.token_storage"
        tagRepo: "@tag.repository.service"
    tags:
        - { name: doctrine.event_listener, event: postPersist, connection: default }

我能找到的大多数答案都建议注入服务容器,但我真的不想这样做。有没有办法正确解决这个问题?

UPD:这是监听器的代码。在我尝试注入 TagRepository 之前一切正常

class ConnectListener
{
/**
 * @var TokenStorage
 */
private $tokenStorage;

/**
 * @var TagRepository
 */
private $tagRepo;

/**
 * @param TokenStorage $tokenStorage
 * @param TagRepository $tagRepo
 */
public function __construct(TokenStorage $tokenStorage, TagRepository $tagRepo)
{
    $this->tokenStorage = $tokenStorage;
}
/**
 * @param LifecycleEventArgs $args
 * @return void
 */
public function postPersist(LifecycleEventArgs $args)
{
    $entity = $args->getEntity();
    $entityManager = $args->getEntityManager();

    if ($entity instanceof Person) {
        $user = $this->tokenStorage->getToken()->getUser();
        $visibility = new PersonVisibility($entity, $user);
        $visibility->setVisibilityType(PersonVisibility::VT_CREATED);
        $entityManager->persist($visibility);
        $entityManager->flush();
    }
}
}

【问题讨论】:

  • 能否请您也添加您的事件监听器的代码?
  • @KhorneHoly - 在我回到家之前,再过 8 小时将无法这样做。但是此时与 tagRepo 没有任何关系,在我添加 tagRepo 之前一切都很好 - 在 postPersist 上,我正在从 tokenStorage 检索当前用户 ID 并使用它在连接 Person 和 Users 表的表中创建记录 - 没有任何关系到 Tag 和 TagRepository。
  • @KhorneHoly - 完成,这里是听众
  • 呃,据我所知,你甚至不使用$tagRepo?或者这会改变吗?
  • @lxg - 好吧,当然会改变)至少如果我弄清楚如何处理异常

标签: php symfony doctrine-orm


【解决方案1】:

只要 TagRepository 是 EntityRepository 的后代,请尝试在 postPersist 事件中获取其实例。像这样:

// using full classname:
$tagRepo = $entityManager->getRepository("Application\Bundle\PersonBundle\Entity\TagRepository");
// alternatively:
$tagRepo = $entityManager->getRepository("ApplicationPersonBundle:Tag");

【讨论】:

    【解决方案2】:

    你也可以更改你的仓库声明,不要使用工厂并使用one of these 2 methods

    这将避免循环引用,并且比使用 EntityManager 类更干净。

    【讨论】:

      猜你喜欢
      • 2021-01-14
      • 2014-07-12
      • 2018-04-14
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 2021-03-12
      • 1970-01-01
      • 2018-06-01
      相关资源
      最近更新 更多