8

Symfony generator generated the following class of repository:

namespace AppBundle\Repository;
use AppBundle\Entity\GroupEntity;

/**
 * GroupEntityRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class GroupEntityRepository extends \Doctrine\ORM\EntityRepository
{


}

services.yml:

group_entity_repository:
         class: AppBundle\Repository\GroupEntityRepository
         arguments: ["@doctrine.orm.entity_manager", AppBundle\Entity\GroupEntity]

I configured services.yml wrongly, but I do not now what to use as second argument. So I get the error:

Catchable Fatal Error: Argument 2 passed to Doctrine\ORM\EntityRepository::__construct() must be an instance of Doctrine\ORM\Mapping\ClassMetadata, string given, called in E:\other\dropbox\Dropbox\programavimas\kodo pavyzdziai\htdocs\users_admin_demo\var\cache\dev\appDevDebugProjectContainer.php on line 1626 and defined

How to fix it? I cannot see in the documentation, it just showed the code for generator and final generated class but no services config.

Jakub Matczak
  • 15,341
  • 5
  • 46
  • 64
Dariux
  • 3,953
  • 9
  • 43
  • 69
  • Found [this topic](http://stackoverflow.com/questions/17228417/symfony-2-creating-a-service-from-a-repository), it probably can help you. – Ugo T. Jul 21 '16 at 13:34

3 Answers3

20

Recommended as of Symfony 3.3:

As of Symfony 3.3 it is recommended to use the actual class name as service id (read this and this).

AppBundle\Repository\GroupEntityRepository:
    factory: 'Doctrine\ORM\EntityManagerInterface:getRepository'
    arguments:
        - AppBundle\Entity\GroupEntity

Original answer:

You can configure your repository service like this:

group_entity_repository:
    class: AppBundle\Repository\GroupEntityRepository
    factory: ["@doctrine.orm.entity_manager", getRepository]
    arguments:
        - AppBundle\Entity\GroupEntity

You will probably never want to invoke the repository constructor yourself. Therefore this approach just uses the entity_manager to get the repository. The service container bascially uses this code to get the repository:

$container->get('doctrine.orm.entity_manager')->getRepository('AppBundle\Entity\GroupEntity');
Tobias Xy
  • 2,039
  • 18
  • 19
  • You are the god. Ok, now how should I find this information? My problem is finding simple information very long I guess. I was working by this page: http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes And if I get reposotory your way, I get error "You have requested a non-existent service "appbundle\entity\groupentity"." But when I ask $groupRepo = $this->container->get('group_entity_repository'); - it works. – Dariux Jul 21 '16 at 13:45
  • Here you can find information about using factories for service definition: http://symfony.com/doc/current/components/dependency_injection/factories.html It is not specific for repositories, but should explain how it works in general. – Tobias Xy Jul 21 '16 at 13:49
  • Another good source of information is the google search bar. Not to be overly snarky but this question has been asked and answered dozens (if not hundreds) of times. Try copy/pasting your title into google and see what comes up. The same searching technique can be used for quite a few other things as well. – Cerad Jul 21 '16 at 13:58
  • @Cerad - actually now I see similar, but before asking I tried to google and did not see. Or I maybe saw things like 'factory' and thought its not what I need and so skipped such answers. I had worked on project with symfony and I do not remember factory things for this. Or maybe did not notice :/ – Dariux Jul 21 '16 at 14:44
  • Recent advances in Symfony are depreciating the alias, so you can/should just use the class name and remove that key. – beltouche Oct 11 '17 at 19:48
  • Now I am not able to find same examle in xml. I am trying already 45 minutes. – Darius.V Dec 05 '18 at 15:22
7

Since Symfony 3.4 you can avoid factory and use a TagRepository service that extends ServiceEntityRepository class instead of directly EntityRepository.

use AppBundle\Entity\GroupEntity;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

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

With this method, your service would be automatically registered with autowiring feature.

You can also do better in all Symfony version by using composition over inheritance.

final class GroupEntityRepository
{
    /** @var EntityManagerInterface */
    private $entityManager;

    /** @var ObjectRepository */
    private $objectRepository;

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

This service can also be autowiring. You can go further by respecting the SOLID principle and create an interface. There is a good explanation in this article (Repository Pattern in Symfony)

Fabien Salles
  • 1,101
  • 15
  • 24
0

Example SF 3.4 how to make in xml:

<service id="vop.sales.payment.entity_repository.billing_status"
                 class="Vop\Sales\PaymentBundle\Entity\BillingStatusRepository">
            <factory service="doctrine.orm.entity_manager" method="getRepository"/>
            <argument>Vop\Sales\PaymentBundle\Entity\BillingStatus</argument>
        </service>
Darius.V
  • 737
  • 1
  • 13
  • 29