Symfony 3.3 - Entity Manager injection into services with multiple database?
Asked Answered
S

1

1

I have recently added a new database to my Symfony 3.3 application. Then my services with injected entity manager are no longer working and return the following error:

Cannot autowire service "RouterBundle\Utils\RoutersUtils": argument "$em" of method "__construct()" references class "Doctrine\ORM\EntityManager" but no such service exists. Try changing the type-hint to one of its parents: interface "Doctrine\ORM\EntityManagerInterface", or interface "Doctrine\Common\Persistence\ObjectManager".

So my config.yml file is now like :

# Doctrine Configuration
doctrine:
    dbal:
        default_connection: router
        connections:
            router:
                driver: pdo_mysql
                host: '%database_host%'
                port: '%database_port%'
                dbname: '%database_router_name%'
                user: '%database_router_user%'
                password: '%database_router_password%'
                charset: utf8mb4
                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci
                    row_format: DYNAMIC
            app:
                driver: pdo_mysql
                host: '%database_host%'
                port: '%database_port%'
                dbname: '%database_app_name%'
                user: '%database_app_user%'
                password: '%database_app_password%'
                charset: utf8mb4
                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci

    orm:
        default_entity_manager: router
        entity_managers:
            router:
                connection: router
                mappings:
                    RouterBundle:  ~
                dql:
                    string_functions:
                        # Match agains should have the path to the Sha1 class created in the previous step
                        SHA1: RouterBundle\Extensions\Doctrine\Sha1
            app:
                connection: app
                mappings:
                    AppBundle: ~

One of my service like :

<?php

namespace RouterBundle\Utils;
use Doctrine\ORM\EntityManager;

class RoutersUtils
{

    protected $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

...

and my services.yml ( I tried to add this arguments but doesn't work)

...
RouterBundle\Utils:
    public: true
    arguments:
        - '@doctrine.dbal.router_connection' 
...

Any idea how to inject the correct Entity Manager? Can I also inject entity manager by default using the "default_entity_manager: router" parameters in teh config file ?

Thanks for the help !

Pierre

Sightly answered 9/3, 2018 at 14:29 Comment(1)
Maybe inject ManagerRegistry? matthiasnoback.nl/2014/05/…Doting
T
1

You cannot autowiring by using the EntityManagerInterface if you have many managers. You will have to pick the right manager in your service definition for each service.

RouterBundle\Utils:
    $em: '@your_entity_manager_service'

PS : You should consider upgrading to sf3.4 as 3.3 is not maintenaited anymore. It also comes with local binding, which will be really useful for what you want to do.

See: https://symfony.com/blog/new-in-symfony-3-4-local-service-binding

Tomtom answered 9/3, 2018 at 14:49 Comment(7)
Hi Fabien, thank you so much.. I almost there but I get this error : The service "RouterBundle\Utils\RoutersUtils" has a dependency on a non-existent service "doctrine.orm.entity_manager.router". Is your solution for 3.4 only or it works for 3.3 ?Sightly
( even if I try doctrine.orm.entity_managers.router or doctrine.orm.default_entity_manager )Sightly
it works with $em: '@doctrine.orm.entity_manager' and I don't understand why !!Sightly
PS : you are right, 3.4 has default arguments injections. It'd be quite useful in my case...Sightly
Actually, I did not test the service name. If you use many managers, you may find their services names using debug:container commandTomtom
My solution works on 3.3, but with the correct service name, I just edited to avoid confusingTomtom
Actually you can autowire EntityManagerInterface but it injects the default EntityManager for you.Affidavit

© 2022 - 2024 — McMap. All rights reserved.