Navigation Menu

Skip to content
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

Repository as service #11155

Closed
bentcoder opened this issue Mar 14, 2019 · 7 comments
Closed

Repository as service #11155

bentcoder opened this issue Mar 14, 2019 · 7 comments
Labels
Milestone

Comments

@bentcoder
Copy link

bentcoder commented Mar 14, 2019

Hi,

As in usage of repository classes the Internet is full of blog posts that often say "Do not dependency inject Entity Manager anywhere", "Entity Manager closed", "This happens if your entity uses multiple Entity Managers" so on. There are many examples and many people are confused as a result. All people want is to create a repository (but how exactly) and inject it to wherever they need it - e.g. a Service class.

I think it is worth putting some kind of example (the best practise) in the Doc and explain why repository should be done that particular way. To me the example should encourage people from decoupling themselves from the Doctrine and composition is more ideal than the inheritance etc.

If no action will be taken in the Doc, could please someone show us an example here? Or maybe vote on one the examples below please. I believe @Ocramius 's input here would add a great value!

Thanks

Examples I've seen -

1

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

class HelloRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Hello::class);
    }
}

2

use Doctrine\ORM\EntityManagerInterface;

class HelloRepository
{
    private $entityManager;
    private $objectRepository;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
        $this->objectRepository = $this->entityManager->getRepository(Hello::class);
    }
}

3

use Doctrine\ORM\EntityRepository;
 
class HelloRepository
{
    private $entityRepository;
 
    public function __construct(EntityRepository $entityRepository)
    {
        $this->entityRepository = $entityRepository;
    }
}

4

use Doctrine\Common\Persistence\ManagerRegistry;

class HelloRepository
{
    private $managerRegistry;

    public function __construct(ManagerRegistry $managerRegistry)
    {
        $this->managerRegistry = $managerRegistry;
    }
}
@kunicmarko20
Copy link
Contributor

Why do you need the entity manager as a prop in the 2. example?

@Ocramius
Copy link
Contributor

@kunicmarko20 usually for persistence operations:

public function store(MyAggregate $aggregate) : void
{
    $this->entityManager->persist($aggregate);
    $this->entityManager->flush();
}

@kunicmarko20
Copy link
Contributor

Ah, thanks for the explanation @Ocramius. What would you suggest here?

@bentcoder
Copy link
Author

Presenting my findings below.

I won't bother sharing the memory usage and response speed data but in the case of test 1 and test 3 it is nearly identical. However, the test 2 just goes out of the window compared to others. Based on what we see below, I am assuming that the test 1 is the ideal way of using Repositories in Symfony application. The reason why I also didn't choose the test 3 is because dependency injecting EM has always been discouraged everywhere on the web. @Ocramius Do you think my assumption reliable? :)

TEST REPO 1

use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

class UserRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, User::class);
    }

    public function findAllCustom(): array
    {
        return $this->createQueryBuilder('u')
            ->getQuery()
            ->getResult();
    }

    public function persistCustom(): void
    {
        $this->getEntityManager()->persist(new User());
        $this->getEntityManager()->flush();
    }
}

1-compressor


TEST REPO 2 :(

use App\Entity\User;
use Doctrine\Common\Persistence\ManagerRegistry;

class UserRepository
{
    private $managerRegistry;

    public function __construct(ManagerRegistry $managerRegistry)
    {
        $this->managerRegistry = $managerRegistry;
    }

    public function findAllCustom(): array
    {
        return $this->managerRegistry->getRepository(User::class)->createQueryBuilder('u')
            ->getQuery()
            ->getResult();
    }

    public function persistCustom(): void
    {
        $this->managerRegistry->getManager()->persist(new User());
        $this->managerRegistry->getManager()->flush();
    }
}

2-compressor


TEST REPO 3

use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;

class UserRepository
{
    private $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function findAllCustom(): array
    {
        return $this->entityManager->getRepository(User::class)->createQueryBuilder('u')
            ->getQuery()
            ->getResult();
    }

    public function persistCustom(): void
    {
        $this->entityManager->persist(new User());
        $this->entityManager->flush();
    }
}

3-compressor

@carsonbot
Copy link
Collaborator

Thank you for this issue.
There has not been a lot of activity here for a while. Has this been resolved?

@carsonbot
Copy link
Collaborator

Friendly reminder that this issue exists. If I don't hear anything I'll close this.

@javiereguiluz javiereguiluz added this to the 4.4 milestone Jan 8, 2021
@carsonbot
Copy link
Collaborator

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants