Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple entity managers in Symfony 3.3 seams to not work as service arguments

I have configured two connections to the database. One connection is called user and other is called client. This is the configuration in the config.yml file:

doctrine:
    dbal:
        default_connection: client
        connections:
            client:
                driver: pdo_mysql
                host: '%client_database_host%'
                port: '%client_database_port%'
                dbname: '%client_database_name%'
                user: '%client_database_user%'
                password: '%client_database_password%'
                charset: UTF8
                mapping_types:
                    enum: string
            user:
                driver: pdo_mysql
                host: '%user_database_host%'
                port: '%user_database_port%'
                dbname: '%user_database_name%'
                user: '%user_database_user%'
                password: '%user_database_password%'
                charset: UTF8
                mapping_types:
                    enum: string

    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        default_entity_manager: ~
        entity_managers:
            client:
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    ProjectModelBundle: ~
                connection: client
            user:
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    BaseModelBundle: ~
                    ProjectModelBundle: ~
                connection: user

But I am always getting the first entity manager no matter what. This is how I am using entity manager's in services:

# BASE
    htec.project_model_bundle.repository.database.client_base:
        class: Project\BaseModelBundle\Repository\Database\DatabaseRepository
        arguments: ['@service_container', '@doctrine.orm.client_entity_manager', '@form.factory']

    htec.project_model_bundle.repository.database.user_base:
        class: Project\BaseModelBundle\Repository\Database\DatabaseRepository
        arguments: ['@service_container', '@doctrine.orm.user_entity_manager', '@form.factory']

But no matter what I do, I always get the first entity manager that I have defined under orm->entity_managers settings. For example if configure orm like this:

orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        default_entity_manager: ~
        entity_managers:
            client:
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    ProjectModelBundle: ~
                connection: client
            user:
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    BaseModelBundle: ~
                    ProjectModelBundle: ~
                connection: user

I will always get the client entity manager even if I supply '@doctrine.orm.user_entity_manager' as service argument.

If I configure orm like this:

orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        default_entity_manager: ~
        entity_managers:
            user:
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    BaseModelBundle: ~
                    ProjectModelBundle: ~
                connection: user
            client:
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    ProjectModelBundle: ~
                connection: client

I will always get the user entity manager even if I supply '@doctrine.orm.client_entity_manager' as service argument.

What am I doing wrong here?

like image 809
Caslav Sabani Avatar asked Nov 22 '17 18:11

Caslav Sabani


1 Answers

Recently I had a similar issue. The comment of @dbrumann gave me a good clue for resolve it. I used the next approach:

  1. If you use the console command debug:autowiring you will see there is a service aliased as doctrine.

    Doctrine\Common\Persistence\ManagerRegistry alias to doctrine
    
  2. You can get access to that service in your target class by type-hinting, put the name of the service class (or interface) as argument in the constructor of your target class.

  3. Now you can access all the methods of the service in your target class, by using the method getManager() you will get any of your managers:

    use Doctrine\Common\Persistence\ManagerRegistry;
    
    $protected $managerRegistry;
    
    public function __construct(ManagerRegistry $managerRegistry)
    {
        $this->managerRegistry = $managerRegistry;
    }
    
    public function foo()
    {
        // asuming your managers names are default and second
        $firstManager = $this->managerRegistry->getManager('default');
        $secondManager = $this->managerRegistry->getManager('second');
    }
    
like image 71
Hokusai Avatar answered Nov 11 '22 23:11

Hokusai