How to inject specific Doctrine Entity Manager in Symfony2?

13,516

Answer at 18/02/13

Here is a way to pass a specific entity manager from services.yml
Doctrine generates a new service name relative to their names.

Example:

@doctrine.orm.default_entity_manager

In this case, it generates 2 others entity manager

@doctrine.orm.main_entity_manager
@doctrine.orm.sub_entity_manager

The argument passed is a Doctrine\ORM\EntityManager object

In my case:

services.yml

submanager:
    arguments: [ @doctrine.orm.sub_entity_manager ]

Update 22/08/13

An alternative to this would be to directly give the repository instead of the manager.

To do such, you must create a service which will hold the repository.

services.yml

services:
    acme.foo_repository:
        class: Doctrine\Common\Persistence\ObjectRepository
        factory_service: doctrine.orm.main_entity_manager
        factory_method:  getRepository
        arguments:
            - "AcmeMainBundle:Foo"

We let doctrine generate the given repository.
Then we can inject it in another service

services:
    mainmanager:
        class: Acme\MainBundle\MainManager
        arguments:
            - @acme.foo_repository
Share:
13,516

Related videos on Youtube

Touki
Author by

Touki

Mostly a php developper on symfony2 framework and a bit of silex but also having common skills in front-end developpement with javascript, html and css. I'm prone to open source projects and I love oop and most of its rules like "Don't be STUPID GRASP SOLID", trying to use them everyday, and learning from it, everyday. I'm never against learning something, I don't have the pride knowing everything, but if I do on a specific subject, I'm glad sharing what I know. If I'm wrong at anytime on an answer, or a question, please feel free to correct me explaining why I was wrong, and how I can improve my answer.

Updated on September 14, 2022

Comments

  • Touki
    Touki over 1 year

    Working on several projects which use the same database, we made a Symfony2 Bundle to map all common functions.

    Now the issue is that we have a second database, and we need the same kind of service, just as the first one.

    config.yml

    doctrine:
      dbal:
        default_connection: main
        connections:
          main:
            /* ... */
          sub:
            /* ... */
    
      orm:
          default_entity_manager:   main
          entity_managers:
              main:
                  connection:       main
                  mappings:
                      AcmeMainBundle: ~
              sub:
                  connection:       sub
                  mappings:
                      AcmeSubBundle: ~
          auto_generate_proxy_classes: %kernel.debug%
    

    @AcmeMainBundle > services.yml

    services:
        mainmanager:
          class: Acme\MainBundle\MainManager
          arguments: [ @doctrine.orm.entity_manager ]
    

    Acme\MainBundle\MainManager

    class MainManager
    {
        public function __construct(EntityManager $em)
        {
            $em->getRepository('AcmeMainBundle:Foo');
        }
    }
    

    This set works fine, I get all expected results since default_entity_manager is set to main which is the right EntityManager.

    But now here's the issue.

    @AcmeSubBundle > services.yml

    submanager:
      class: Acme\SubBundle\SubManager
      arguments: [ @doctrine.orm.entity_manager ]
    

    Acme\SubBundle\SubManager

    class SubManager
    {
        public function __construct(EntityManager $em)
        {
            $em->getRepository('AcmeSubBundle:Bar'); // Throws exception
        }
    }
    

    Unknown entity namespace alias AcmeSubBundle

    Since EntityManager goes into main by default.

    My question is, is there a "clean" way to inject a specific entity manager as argument in services.yml ?