Symfony2 is fantastic when coupled with Doctrine, but unfortunately Doctrine has its limitations and does not inherently support dynamic EntityManager connections, because the parameters for each connection must be defined and loaded at the kernel level.

This assumes that each of the connections have an identical schema mapped by Doctrine2.

My live implementation functions for a single/multi tenant shared architecture in which connection parameters are encrypted and housed in MasterDatabase, while ChildDatabase1, ChildDatabase2, all have the exact same schema, but isolated data for a variety of business reasons.

There are several components to making this work:

  1. app/config/parameters.yml
  2. app/config/config.yml
  3. app/config/services.yml
  4. MyApp/Services/ApplicationConnector.php


# Master database connection
database_driver: pdo_mysql
database_host: ~
database_port: ~
database_name: master_database
database_user: master_user
database_password: master_password

# This is the connection loaded initially. This
# connection must exist, but can be otherwise empty.
child_database_driver: pdo_mysql
child_database_host: ~
child_database_port: ~
child_database_name: child_db
child_database_user: child_db_user
child_database_password: child_db_password


        default_connection: master
                driver:   %database_driver%
                host:     %database_host%
                port:     %database_port%
                dbname:   %database_name%
                user:     %database_user%
                password: %database_password%
                charset:  UTF8
                driver:   %child_database_driver%
                host:     %child_database_host%
                port:     %child_database_port%
                dbname:   %child_database_name%
                user:     %child_database_user%
                password: %child_database_password%
                charset:  UTF8

        default_entity_manager: master
        auto_generate_proxy_classes: %kernel.debug%
                connection: master
                connection: child


        class: MyApp\Services\ApplicationConnector
            - [ setContainer, [ @service_container ] ]



 *    Dynamically set a specific EntityManager database connection.

namespace MyApp\Services;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ApplicationConnector implements ContainerAwareInterface

     * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
    public function setContainer(ContainerInterface $container = NULL)
        $this->container = $container;

     * @param $dbName
     * @param $dbUser
     * @param $dbPassword
     * @param $dbHost
     * @param bool $reset
     * @throws \Exception
    public function resetConnection($dbName, $dbUser, $dbPassword, $dbHost, $reset = false)

        try {

            //establish the connection
            $connection = $this->container->get('doctrine.dbal.applications_connection');


            if ($reset && $connection->isConnected()) {

            $refConn = new \ReflectionObject($connection);
            $refParams = $refConn->getProperty('_params');
            $refParams->setAccessible('public'); //we have to change it for a moment

            $params = $refParams->getValue($connection);
            $params['dbname'] = $dbName;
            $params['user'] = $dbUser;
            $params['password'] = $dbPassword;
            $params['host'] = $dbHost;

            $refParams->setValue($connection, $params);

            if ($reset) {

        catch (\Exception $e) {
            throw $e;


Usage in a Controller

//this is the master EntityManager
$em = $this->getDoctrine()->getManager();

//this is the child EntityManager
$childEm = $this->getDoctrine()->getManager('child');

//If we want to change the childEm to a different database:

 * IMPORTANT: The $reset parameter is used to clear all Units of Work fro
 * the EntityManager, this means anything that was not previously flushed
 * will be lost if you do $reset = true.
 * Separately, $reset is necessary if you want to apply changes across 
 * multiple EntityManagers in one Controller. Make sure you flush, then 
 * $reset, and you will be good to go.

 * get your new database parameters here..
$connector = $this->container->get('application_connector');
$connector->resetConnection($dbName, $dbUser, $dbPassword, $dbHost, $reset = true);

//childEM is now connected to the new database.
$childEm = $this->getDoctrine()->getManager('child');


Categories: Random


Jehan · October 21, 2015 at 2:56 am

Thanks a lot! It’s really a great help to me !

Sudin · November 25, 2015 at 6:51 am

If there are 10 different database connected with dynamic connection. What is the solution for schema update ?

    Jake Litwicki · November 25, 2015 at 9:49 am

    I wouldn’t recommend having 10 simultaneous connections, but if you needed that in your use case, you’d want to make sure they were all uniquely named, and then a schema update would require some modifications to doctrine-migrations (assuming you’re using Doctrine). You can do this with the –em parameter in your migrations command(s).

beez · January 28, 2017 at 6:14 pm

Great bit of code! Thanks a lot! Could you help with one teeny-tiny thing tho, please? Apparently resetting the entity manager is now deprecated in Symfony 3.2 (does work but will stop once they release 4.0), do you have any idea on how to refactor that line to be future-proof? Thanks!

    Jake Litwicki · February 7, 2017 at 10:15 am

    That’s a good question; where did you find that? I’ll take a look and see what we can do!

Inma Ruiz · March 14, 2017 at 2:22 am

Hello jake
First of all apologies for my English. (It is a translation of Spanish and I do not know how it will come out).
The solution you raise in your article is very well explained and has worked perfectly. It was a great help because she was very lost.
I have the same application that uses several client databases. I have the default connection that contains the bd with the connection data of each bd of the clients and the dynamic connection that I am assigning the bd of the client. This I have already been able to configure with your code.

Now I have passed the following problem: the Fosuserbundle configuration.
Each bd of my clients have their own table of users independent of the others. But I do not know how I can do so that the login of the application is made against the taba users of the bd of the selected client.

I tried to modify the loginAction of the SecurityControler driver whose parent is FOSUserBundle but I did not get it to work.

Do you know how I have to do it?
Thanks in advance.



    Jake Litwicki · March 23, 2017 at 9:30 pm

    I try to avoid FOSUserBundle because it does not allow the type of wild customizations I typically need to accommodate things easily for my clients. Can you be a little more specific about what isn’t working and maybe I can help; if not I know the FOS crew is fantastic and I’m sure has plenty of great resources available.

      Inma Ruiz · March 24, 2017 at 1:46 am

      Thanks Jake, I’ll see if the FOS team clarifies something.

andres · February 25, 2019 at 8:54 am

Hi Jake,

I have 2 different databases, one pointing to sql server and the other to mysql. I am trying to connect to the other database connection in a repository, you know how to make this connection, taking into account that in the entity repository it will always detect the default connection. I link but I have not had success from the repository, thank you very much.

    Jake Litwicki · February 27, 2019 at 3:31 pm

    You need to make sure when you’re accessing `$this->getEntityManager()` within the Repository you’re specifying which connection to use, or it will always use the default.

BR · March 7, 2021 at 2:32 am

Hi Jake, you are fab as always. Thanks for the article it helped me a lot. while connecting the multiple entity manager I am having below problem, “Property _params does not exist”. I have explained the issue in details. can you have a look. Thank you.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *