Менеджер сущностей Doctrine, использующий неправильное соединение - PullRequest
0 голосов
/ 01 октября 2019

Согласно документам 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

, а затем попытался сделать запрос с помощью

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

Однако результатом $meterEntityManager->getRepository(Entity\Meter::class)->find($meterId) является строка из соединения с базой данных с именемdefault, а не тот, который назван meter - как если бы код был

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

Когда я проверяю соединение с $meterEntityManager->getConnection()->getParams(), он правильно перечисляет параметры для соединения meterвместо соединения default, поэтому я могу получить строку из соединения с базой данных meter, выполняя запросы непосредственно к объекту соединения:

$meterEntityManager = $this->getDoctrine()->getManager('meter');
$stmt = $meterEntityManager->getConnection()->prepare('SELECT * FROM meter WHERE id = :id');
$stmt->execute(['id' => $meterId]);
$meter = $stmt->fetch();

Но в конечном итоге я хочу получить строки с помощью предложенных методовна getRepository(Entity\Meter::class), поэтому возвращаемые данные автоматически объединяются в сущности доктрины. Кажется, есть несоответствие между соединением, используемым $meterEntityManager->getRepository(Entity\Meter::class) и $meterEntityManager->getConnection(). Почему это? Имеет ли это какое-то отношение к менеджерам сущностей, использующим разные соединения, но разделяющим одни и те же сопоставления с сущностями?

1 Ответ

1 голос
/ 01 октября 2019

Основная проблема здесь заключается в том, что класс ServiceEntityRepository просматривает список менеджеров сущностей и использует первый, который поддерживает данную сущность. Что хорошо, за исключением случаев, когда у вас есть сущности, поддерживаемые несколькими менеджерами сущностей. Решение состоит в том, чтобы перейти к «старой школе» и расширить класс EntityRepository вместо того, что в сущности является контейнером ServiceEntityRepository.

use Doctrine\ORM\EntityRepository;
class MeterRepository extends EntityRepository
{
    // Note: Do not override the constructor here

Вы также должны добавить каталог App \ Repository в список исключенных каталогов. в services.yaml.

Причиной создания ServiceEntityRepository было разрешение контейнеру Symfony автоматически подключать репозитории и вставлять их непосредственно в другие службы. Это также позволяет разработчику добавлять дополнительные зависимости в хранилище, если они того пожелают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...