使用错误连接的 Doctrine 实体管理器

Tim*_*Tim 2 php symfony doctrine-orm

根据该Symfony的文档,多个实体管理器可以通过把它们列出来配置config/packages/doctrine.yaml,然后在这样的控制器选择特定的实体管理器:$this->getDoctrine()->getManager('customer');

我设置了我的config/packages/doctrine.yaml

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                # configure these for your database server
                url: '%env(DATABASE_URL)%'
                driver: 'pdo_mysql'
                server_version: '8.0'
                charset: utf8mb4
            meter:
                # configure these for your database server
                url: '%env(DATABASE_METER_URL)%'
                driver: 'pdo_mysql'
                server_version: '8.0'
                charset: utf8mb4

    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    App:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity'
                        prefix: 'App\Entity'
                        alias: App
            meter:
                connection: meter
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    App:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity'
                        prefix: 'App\Entity'
                        alias: App
Run Code Online (Sandbox Code Playgroud)

然后尝试进行查询

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                # configure these for your database server
                url: '%env(DATABASE_URL)%'
                driver: 'pdo_mysql'
                server_version: '8.0'
                charset: utf8mb4
            meter:
                # configure these for your database server
                url: '%env(DATABASE_METER_URL)%'
                driver: 'pdo_mysql'
                server_version: '8.0'
                charset: utf8mb4

    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    App:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity'
                        prefix: 'App\Entity'
                        alias: App
            meter:
                connection: meter
                naming_strategy: doctrine.orm.naming_strategy.underscore
                mappings:
                    App:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity'
                        prefix: 'App\Entity'
                        alias: App
Run Code Online (Sandbox Code Playgroud)

但是,结果$meterEntityManager->getRepository(Entity\Meter::class)->find($meterId)是来自名为 的数据库连接的行default,而不是名为的行meter——就好像代码已经

$meterEntityManager = $this->getDoctrine()->getManager('meter');
$meter = $meterEntityManager->getRepository(Entity\Meter::class)->find($meterId);
Run Code Online (Sandbox Code Playgroud)

当我检查与$meterEntityManager->getConnection()->getParams()它的连接时,它会正确列出连接的参数meter而不是default连接,因此我可以meter通过直接在连接对象上执行查询来从数据库连接中获取一行:

$entityManager = $this->getDoctrine()->getManager('default');
$meter = $entityManager->getRepository(Entity\Meter::class)->find($meterId);
Run Code Online (Sandbox Code Playgroud)

但最终我想通过提供的方法获取行,getRepository(Entity\Meter::class)因此返回的数据会自动水合到原则实体中。$meterEntityManager->getRepository(Entity\Meter::class)和使用的连接之间似乎存在不一致$meterEntityManager->getConnection()。为什么是这样?它是否与使用不同连接但共享相同实体映射的实体管理器有关?

Cer*_*rad 5

这里的基本问题是 ServiceEntityRepository 类遍历实体管理器列表并使用支持给定实体的第一个。这很好,除非您碰巧有多个实体管理器支持的实体。解决方案是“老派”并从 EntityRepository 类扩展,而不是基本上是容器感知 ServiceEntityRepository。

use Doctrine\ORM\EntityRepository;
class MeterRepository extends EntityRepository
{
    // Note: Do not override the constructor here
Run Code Online (Sandbox Code Playgroud)

您还必须将 App\Repository 目录添加到 services.yaml 中的排除目录列表中。

ServiceEntityRepository 的原因是允许 Symfony 容器自动装配存储库并将它们直接注入其他服务。如果他们愿意,它还允许开发人员将额外的依赖项注入存储库。