title: Dynamic database connection symfony2
body: <p>My symfony2 project has a main database and many child databases. Each child database is created for each user, the database credentials are stored in the main database. When the user logins, the user specific database credentials are fetched from the main database and the child database connection ideally should be established.
  I googled for the same, and I came accross a number of solutions and finally did the following:</p>
  
  <pre><code>#config.yml
  
  doctrine:
  dbal:
      default_connection:       default
      connections:
          default:
              dbname:           maindb
              user:             root
              password:         null
              host:             localhost
          dynamic_conn:
              dbname:           ~
              user:             ~
              password:         ~
              host:             localhost
  orm:
      default_entity_manager:   default
      entity_managers:
          default:
              connection:       default
              auto_mapping:     true
          dynamic_em:
              connection:       dynamic_conn
              auto_mapping:     true
  </code></pre>
  
  <p>I created a default connection to connect to the main database and an empty connection for the child database, similarly I created entity managers.
  Then I created default event listener and added the following code to the 'onKernelRequest':</p>
  
  <pre><code>public function onKernelRequest(GetResponseEvent $event) //works like preDispatch in Zend
  {
      //code to get db credentials from master database and stored in varaiables
      ....
      $connection = $this-&gt;container-&gt;get(sprintf('doctrine.dbal.%s_connection', 'dynamic_conn'));
      $connection-&gt;close();
  
      $refConn = new \ReflectionObject($connection);
      $refParams = $refConn-&gt;getProperty('_params');
      $refParams-&gt;setAccessible('public'); //we have to change it for a moment
  
      $params = $refParams-&gt;getValue($connection);
      $params['dbname'] = $dbName;
      $params['user'] = $dbUser;
      $params['password'] = $dbPass;
  
      $refParams-&gt;setAccessible('private');
      $refParams-&gt;setValue($connection, $params);
      $this-&gt;container-&gt;get('doctrine')-&gt;resetEntityManager('dynamic_em');
      ....
  }
  </code></pre>
  
  <p>The above code sets the child database parameters and resets the dynamic_em entity manager.</p>
  
  <p>When I do the following in some controller, it works fine and the data if fetched from the child database.</p>
  
  <pre><code>$getblog= $em-&gt;getRepository('BloggerBlogBundle:Blog')-&gt;findById($id); //uses doctrine
  </code></pre>
  
  <p>But, when I use security context as seen in the following code, I get an error 'NO DATABASE SELECTED'.</p>
  
  <pre><code>$securityContext = $this-&gt;container-&gt;get('security.context');
  $loggedinUserid = $securityContext-&gt;getToken()-&gt;getUser()-&gt;getId();
  </code></pre>
  
  <p><strong>How can I set database connection dynamically and use security context as well?</strong></p>
  
  <p><strong>UPDATE:-</strong></p>
  
  <p>After much time spent on trial and error, and googling around, I realized that <code>security.context</code> is set before the execution of <code>onKernelRequest</code>. Now the question is <strong>how</strong> to inject the database connection details into the security.context, and <strong>where</strong> to inject?</p>
  
  <p>We need to get to a point where the DBAL and security context is set and security token is created, and we can manipulate database connection details.</p>
  
  <p>Hence, as the person in the following link stated, I made changes to my code, as thats exactly what I would want to do.
  <a href="http://forum.symfony-project.org/viewtopic.php?t=37398&amp;p=124413" rel="noreferrer">http://forum.symfony-project.org/viewtopic.php?t=37398&amp;p=124413</a></p>
  
  <p>That leaves me the following code add to my project:</p>
  
  <pre><code>#config.yml //remains unchanged, similar to above code
  </code></pre>
  
  <p>A compiler pass is created as follows:</p>
  
  <pre><code>// src/Blogger/BlogBundle/BloggerBlogBundle.php
  namespace Blogger\BlogBundle;
  
  use Symfony\Component\HttpKernel\Bundle\Bundle;
  use Symfony\Component\DependencyInjection\ContainerBuilder;
  
  use Blogger\BlogBundle\DependencyInjection\Compiler\CustomCompilerPass;
  
  class BloggerBlogBundle extends Bundle
  {
      public function build(ContainerBuilder $container)
      {
          parent::build($container);
  
          $container-&gt;addCompilerPass(new CustomCompilerPass());
      }
  }
  </code></pre>
  
  <p>The compiler pass is as follows:</p>
  
  <pre><code># src/Blogger/BlogBundle/DependencyInjection/Compiler/CustomCompilerPass.php
  
  class CustomCompilerPassimplements CompilerPassInterface
  {
      public function process(ContainerBuilder $container)
      {
          $connection_service = 'doctrine.dbal.dynamic_conn_connection';
          if ($container-&gt;hasDefinition($connection_service))
          {
              $def = $container-&gt;getDefinition($connection_service);
              $args = $def-&gt;getArguments();
              $args[0]['driverClass'] = 'Blogger\BlogBundle\UserDependentMySqlDriver';
              $args[0]['driverOptions'][] = array(new Reference('security.context'));
              $def-&gt;replaceArgument(0, $args[0]);
          }
     }
  }
  </code></pre>
  
  <p>The driver class code is as follows:</p>
  
  <pre><code># src/Blogger/BlogBundle/UserDependentMySqlDriver.php
  
  use Doctrine\DBAL\Driver\PDOMySql\Driver;
  
  class UserDependentMySqlDriver extends Driver
  {    
      public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
      {
          $dbname = .....  //store database name in variable
          $params['dbname'] = $dbname;
          return parent::connect($params, $username, $password, array());
      }
  }
  </code></pre>
  
  <p>The above code were added to my project, and I assume that this is the actual work around for to my problem.</p>
  
  <p>But now I get the following error:</p>
  
  <blockquote>
    <p>ServiceCircularReferenceException: Circular reference detected for
    service "security.context", path: "profiler_listener -> profiler ->
    security.context -> security.authentication.manager ->
    fos_user.user_provider.username_email -> fos_user.user_manager ->
    doctrine.orm.dynamic_manager_entity_manager ->
    doctrine.dbal.dynamic_conn_connection".</p>
  </blockquote>
  
  <p>How, can I get my code to work? I bet that I am doing something wrong here and I would appreciate any hints and help.</p>