Skip to content

Circular reference detected for service "doctrine.orm.default_entity_manager" #29693

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
konshensx16 opened this issue Dec 26, 2018 · 6 comments
Closed

Comments

@konshensx16
Copy link

Symfony version(s) affected: 4.2.1

Description
ServiceCircularReferenceException is thrown when i try to inject a repository in a listener's constructor, one important note is that i have the same exact code that i'm posting right here in a 4.1.6 project and it works just fine, here are the important parts of the code:
PostListener (where seems to be the problem):

<?php

namespace App\Listeners;

use App\Entity\Post;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use App\Repository\AttachmentRepository;

class PostListener
{
    private $attachmentRepository;

    public function __construct(AttachmentRepository $attachmentRepository)
    {
        $this->$attachmentRepository = $attachmentRepository;
    }

    public function preUpdate(Post $post, PreUpdateEventArgs $args)
    {
        dump($this->attachmentRepository->findAll());
    }
}

services.yaml:

services:
    # default configuration for services in *this* file
    #...... default configuration removed for clarity 
    App\Listeners\PostListener:
        tags:
            - { name: doctrine.orm.entity_listener }

Post.php:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PostRepository")
 * @ORM\EntityListeners({"App\Listeners\PostListener"})
 */
class Post
{

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Attachment", mappedBy="post")
     *
     * @var [type]
     */
    private $attachments;
}

Attachment.php:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\AttachmentRepository")
 */
class Attachment
{
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Post", inversedBy="attachments")
     *
     * @var [type]
     */
    private $post;
 
}

How to reproduce
Git repository to recreate the problem: https://github.com/konshensx16/circular-reference
Navigating to localhost:8000/post should be enough since i can't even start the server because of the problem, but if that doesn't work, triggering the PostListener by updating a post's content field should 100% throw the exception.

Additional context
As mentioned before i have the same exact code in version 4.1.6 and it works perfectly fine.

Thank you in advance :)

@eb22fbb4
Copy link

eb22fbb4 commented Dec 27, 2018

You shoud not inject App\Repository\AttachmentRepository into App\Listeners\PostListener,the EntityMangaer is included into Doctrine\ORM\Event\PreUpdateEventArgs:

<?php

namespace App\Listeners;

use App\Entity\Post;
use App\Entity\Attachment;
use Doctrine\ORM\Event\PreUpdateEventArgs;

class PostListener
{
    public function preUpdate(Post $post, PreUpdateEventArgs $args)
    {
        $attachmentRepository = $args->getEntityManager()->getRepository(Attachment::class);
        dump($attachmentRepository->findAll());
    }
}

@konshensx16
Copy link
Author

Hey there mate, thank you for the response,

Yes using the EntityManager that's in $args would work ,but the problem is i have the same exact code where i inject the AttachmentRepository in PostListener's construcor and it worksm which makes me think this is a bug with the new version because i can find any chnages log reporting any changes in terms of injecting Repositories in Listeners.

@javiereguiluz
Copy link
Member

javiereguiluz commented Dec 27, 2018

@konshensx16 thanks for reporting this issue. You said that this works in 4.1.6 but not in 4.2.1. In order to debug this faster, we'd need to know the first version which breaks your app. Could you please try with 4.1.7, 4.1.8, 4.1.9 and 4.2.0 and tell us which is the first version that breaks your app? Thanks!

@xabbuh
Copy link
Member

xabbuh commented Dec 27, 2018

Maybe caused by the same change that causes #29637? Can you check if the commit mentioned there made the difference in your application too?

@konshensx16
Copy link
Author

konshensx16 commented Dec 27, 2018

Hello @javiereguiluz and @xabbuh thanks for replying to this, i just want to address one weird thing i just noticed like 5 minutes ago when i was doing more tests, the code i posted above isn't working obviously and throwing the exception, but this one WORKS and i cannot seem to undertand why:

<?php

namespace App\Listeners;

use App\Entity\Attachment;
use App\Entity\Post; 
use App\Repository\AttachmentRepository; 
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\Security\Core\Security;

class PostListener
{
    // i need to get the current logged in user
    /**
     * @var Security
     */
    private $security;
    /**
     * @var EntityManagerInterface
     */
    private $entityManager; 
    /**
     * @var AttachmentRepository
     */
    private $attachmentRepository;
    
    public function __construct(Security $security,
                                EntityManagerInterface $entityManager,
                                AttachmentRepository $attachmentRepository
    )
    {
        $this->security = $security;
        $this->entityManager = $entityManager;
        $this->attachmentRepository = $attachmentRepository;
    }

    public function preUpdate(Post $post, PreUpdateEventArgs $args)
    {
    	dump($this->attachmentRepository->findAll()); die;
    }

}

You guys have any idea why this would work and the other one (the code in the issue) won't? Does injecting the EntityManagerInterface has something to do with it ?

Edit

Removing the EntityManagerInterface will result in the exception being throw, and this is for the 4.1.6 which i intially said works fine, but when removing the EntityManagerInterface it throws the exception as well, i'm sorry as i was not aware of this.

@zmitic
Copy link

zmitic commented Jan 25, 2019

Did to try lazy services https://symfony.com/doc/current/service_container/lazy_services.html ?

This should do the trick but if not, try injecting repository with @required annotation: https://symfony.com/doc/current/service_container/autowiring.html#autowiring-other-methods-e-g-setters

nicolas-grekas added a commit that referenced this issue Jan 30, 2019
…kas)

This PR was merged into the 3.4 branch.

Discussion
----------

[DI] Fix dumping Doctrine-like service graphs

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #30017 #29637 #29693
| License       | MIT
| Doc PR        | -

I'm unable to provide a reproducer for this, the required service reference graph is too crazy, but that does the job :)

Commits
-------

ed96830 [DI] Fix dumping Doctrine-like service graphs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants