2

I want to change from the default em to an em called 'ps'. The configuration is correct and in the controller I can simply type $this->getManager('ps')->getConnection('ps');.

However I want to create a service with dependency injection which also needs to access this connection.

<?php
namespace AppBundle\Service;

use Doctrine\ORM\EntityManagerInterface;

class HilaService
{

    private $entityManager;
    private $connection;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
        $this->connection = $entityManager->getConnection('ps');

    }

    public function getCategories(){
        $query = $this->connection->query(
            'SQL ....'
        );

        $r = $query->execute();
    }
}

As I can nowhere select the Entity Manager 'ps' it can't also load the connection 'ps', which results in an error:

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'ps_xxx' doesn't exist

Can I somehow pass an argument to the injection? Or Inject somewhat of a 'parent object' to then call ->getManager()?

ptmr.io
  • 2,115
  • 4
  • 22
  • 34

1 Answers1

3

If your service class just needs the connection then it easiest way it make your own connection class and inject it.

namepace AppBundle\Connection;

class PsConnection extends Doctrine\DBAL\Connection
{
}

# doctrine.yaml
doctrine:
    dbal:
        connections:
            ps:
                wrapper_class: AppBundle\Connection\PsConnection

# services.yaml
App\:
    resource: '../src/'
    exclude:
        - '../src/AppBundle/Connection/PsConnection.php'

class HilaService
{
    public function __construct(AppBundle\Connection\PsConnection $conn)

Everything will work as before but you can get the connection directly.

if you really do need the entity manager then you can make a service definition:

# services.yaml
AppBundle\Service\HilaService:
    $entityManager: '@doctrine.orm.ps_entity_manager'

Finally, if you don't want to fool around with any of this stuff you can inject the ManagerRegistry and pull what you need from it.

class HilaService
{
    public function __construct(Doctrine\Common\Persistence\ManagerRegistry $managerRegistry)
    {
        $em = $managerRegistry->getManager('ps'); // or getConnection()
Cerad
  • 48,157
  • 8
  • 90
  • 92
  • Hi and thank you for your answer. Greatly explained triad of methods, however the first one - which indeed seems to be the nicest - does not work for me: `Cannot autowire service "AppBundle\Connection\PsConnection": argument "$params" of method "Doctrine\DBAL\Connection::__construct()" is type-hinted "array", you should configure its value explicitly.` – ptmr.io Jul 30 '18 at 10:19
  • Sorry. You need to add the Connection directory to the exclude section of services.yaml to prevent it from being picked up by autowire. – Cerad Jul 30 '18 at 12:44
  • 1
    @PierredeLESPINAY There are several approaches: https://stackoverflow.com/questions/59266372/how-to-use-symfony-autowiring-with-multiple-entity-managers/59289477#59289477 Personally I like the decorator approach but pick whichever works best for you. – Cerad Mar 04 '20 at 17:48
  • Exactly what I was searching for, thank ! I didn't know about this decorator feature, very useful in that case. – Pierre de LESPINAY Mar 05 '20 at 08:30