使用Symfony中的非默认实体管理器进行自动映射

Using the doctrine-bundle, I'm creating a bundle that requires a different database connection than the default one.

The bundle creates a new entity_manager, that uses the new connection through configuration:

doctrine:
  orm:
    entity_managers:
       default:....
       my_custom_em:
          connection: my_custom_connection
          mappings:
            MyBundle: ~

When trying to access the repository with $this->getContainer()->get('doctrine')->getRepository('MyBundle:AnEntity'); I have the error:

  Unknown Entity namespace alias 'MyBundle'.

But when using the name of the custom entity manager it works : $this->getContainer()->get('doctrine')->getRepository('MyBundle:AnEntity', 'my_custom_em');

There is no way for doctrine to detect that MyBundle should be mapped to this entity manager?

Unfortunately auto_mapping can only be used when one connection is configured, so there is no simple one-line configuration which solve the problem.

Anyway there is a simple solution.

Use the RegistryManager

Anyway, when you call $this->getContainer()->get('doctrine') you get an instance of ManagerRegistry (see the docs), which have a method called getManagerForClass. With this method you can write code that don't rely on the connection configuration.

Your example will become:

$class = 'MyBundle:AnEntity';
$manager = $this->getContainer()->get('doctrine')->getManagerForClass($class);
$manager->getRepository($className)

Define the ObjectManager as a service

If the special handling is required only for one bundle, you can take an even better solution from the previous approach.

You can define a service which will call the RegistryManager for you in a transparent way.

In service.xml you could write:

<parameters>
    <parameter key="my.entity.an_entity.class">Acme\MyBundle\Entity\AnEntity</parameter>
</parameters>

<services>
    <service id="my.manager"
             class="Doctrine\Common\Persistence\ObjectManager"
             factory-service="doctrine" factory-method="getManagerForClass">
         <argument>%my.entity.an_entity.class%</argument>
    </service>

    <service id="my.an_entity_repository"
             class="Doctrine\Common\Persistence\ObjectRepository"
             factory-service="my.manager" factory-method="getRepository">
         <argument>%my.entity.an_entity.class%</argument>
    </service>
</services>

Your example will become:

$class = 'MyBundle:AnEntity';

$repository = $this->getContainer()->get('my.manager')->getRepository($class);
// or
$repository = $this->getContainer()->get('my.an_entity_repository')