如何解决“检测到服务的循环引用”问题问题


How to resolve "Circular reference detected for service" issue?

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

ServiceCircularReferenceException in bootstrap.php.cache line 2129:

检测到服务"doctrine.orm.default_entity_manager"的循环引用,路径:"doctrine.orm.default_entity_manager -> doctrine.dball .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();
    }
}
}

就TagRepository是EntityRepository的后代而言,尝试在postPersist事件中获取其实例。这样的:

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

你也可以改变你的存储库声明,不要使用工厂,使用以下两个方法之一。

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