0

我正在关注这里的文档https://symfony.com/doc/current/reference/configuration/doctrine.html关于设置备用数据库连接以进行读取复制。作为参考,我将 AWS Aurora PostgreSQL 与主要端点和只读端点一起使用。

我已经为我的doctrine.yaml

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                url: '%env(resolve:DATABASE_URL)%'
            read:
                url: '%env(resolve:READ_URL)%'
    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
                auto_mapping: true
                dql:
                    datetime_functions:
                        date_trunc: App\DoctrineExtensions\DateTrunc
                mappings:
                    App:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity'
                        prefix: 'App\Entity'
                        alias: App
            read:
                connection: read
                naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
                auto_mapping: false
                dql:
                    datetime_functions:
                        date_trunc: App\DoctrineExtensions\DateTrunc
                mappings:
                    App:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity'
                        prefix: 'App\Entity'
                        alias: App
        auto_generate_proxy_classes: true

并将只读 orm 称为:

$user = $this->getDoctrine()->getRepository(User::class, 'read')->findOneBy(['email' => $payload['email']]);

举个例子。

如果我调用它,它仍然会转到默认数据库。如果我将其命名错误,Symfony 会按预期抛出异常,因此我可以确认配置正在被拾取并正确加载。

我的配置或调用如何不正确,它仍在从default数据库连接请求,或者有没有更好的方法来定义数据连接的只读副本?我还没有找到任何当前的文档。

4

1 回答 1

1

据此:_

一个实体可以由多个实体管理者管理。但是,当从自定义存储库中的 ServiceEntityRepository 扩展时,这会导致意外行为。ServiceEntityRepository 始终使用为该实体配置的实体管理器。为了解决这种情况,请改为扩展 EntityRepository 并且不再依赖自动装配:

所以你应该确保你的存储库扩展EntityRepository而不是ServiceEntityRepository.

那么您现在应该始终使用ManagerRegistry::getRepository().

所以基本上这会起作用,因为$this->getDoctrine()返回一个ManagerRegistry.

$user = $this->getDoctrine()->getRepository(User::class, 'read')->findOneBy(['email' => $payload['email']]);

缺点是您将无法对存储库本身使用自动装配。

因此,除非您手动传递该存储库,否则这将不起作用。

public function __construct(UserRepository $userRepository)
{
    $this->userRepository = $userRepository;
}
于 2020-12-03T04:40:13.683 回答