Несколько менеджеров сущностей в шлейфах Symfony 3.3 не работают как служебные аргументы
Я настроил два подключения к базе данных. Одно соединение называется пользователем, а другое называется клиентом. Это конфигурация в файле config.yml:
doctrine:
dbal:
default_connection: client
connections:
client:
driver: pdo_mysql
host: '%client_database_host%'
port: '%client_database_port%'
dbname: '%client_database_name%'
user: '%client_database_user%'
password: '%client_database_password%'
charset: UTF8
mapping_types:
enum: string
user:
driver: pdo_mysql
host: '%user_database_host%'
port: '%user_database_port%'
dbname: '%user_database_name%'
user: '%user_database_user%'
password: '%user_database_password%'
charset: UTF8
mapping_types:
enum: string
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
Но я всегда получаю первый менеджер сущности, несмотря ни на что. Вот как я использую диспетчер сущностей в сервисах:
# BASE
htec.project_model_bundle.repository.database.client_base:
class: Project\BaseModelBundle\Repository\Database\DatabaseRepository
arguments: ['@service_container', '@doctrine.orm.client_entity_manager', '@form.factory']
htec.project_model_bundle.repository.database.user_base:
class: Project\BaseModelBundle\Repository\Database\DatabaseRepository
arguments: ['@service_container', '@doctrine.orm.user_entity_manager', '@form.factory']
Но независимо от того, что я делаю, я всегда получаю первый менеджер сущности, который я определил в настройках orm- > entity_managers. Например, если configure orm выглядит следующим образом:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
Я всегда получаю менеджер объектов клиента, даже если я поставлю '@doctrine.orm.user_entity_manager' в качестве аргумента службы.
Если я настрою orm следующим образом:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: ~
entity_managers:
user:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
BaseModelBundle: ~
ProjectModelBundle: ~
connection: user
client:
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
ProjectModelBundle: ~
connection: client
Я всегда получаю менеджер пользовательских сущностей, даже если я поставлю '@doctrine.orm.client_entity_manager' в качестве аргумента службы.
Что я здесь делаю неправильно?
Ответы
Ответ 1
Недавно у меня была аналогичная проблема. Комментарий @dbrumann дал мне хороший ключ к его решению. Я использовал следующий подход:
-
Если вы используете консольную команду debug:autowiring
, вы увидите, что служба называется псевдонимом.
Doctrine\Common\Persistence\ManagerRegistry alias to doctrine
-
Вы можете получить доступ к этой службе в целевом классе с помощью подсказки типа, поместить имя класса обслуживания (или интерфейса) в качестве аргумента в конструкторе целевого класса.
-
Теперь вы можете получить доступ ко всем методам службы в вашем целевом классе, используя метод getManager()
, вы получите любого из ваших менеджеров:
use Doctrine\Common\Persistence\ManagerRegistry;
$protected $managerRegistry;
public function __construct(ManagerRegistry $managerRegistry)
{
$this->managerRegistry = $managerRegistry;
}
public function foo()
{
// asuming your managers names are default and second
$firstManager = $this->managerRegistry->getManager('default');
$secondManager = $this->managerRegistry->getManager('second');
}
Ответ 2
Итак, вы определили службу с именем DatabaseRepository
, которая существует в двух вариантах. В какой-то момент он получает диспетчер сущностей "клиент", а в другой точке он получает "пользовательский" менеджер сущностей?
Я думаю, что он всегда возвращает вам "клиентский" менеджер, скорее всего, потому что это первый раз, когда служба была определена для контейнера службы. Не имеет значения, что вы потом определяете в том же коде .yml
.
Теперь для вас существует большой "почему" риторический вопрос. Почему вы не определили два класса обслуживания, каждый для конкретного менеджера? Если вам действительно нужно это делать, это указывает на серьезные проблемы с дизайном в остальном коде вашего проекта.
Другое предложение: Назовите свои классы несколько более наглядными. Администратор сущности и класс репозитория, безусловно, что-то делают с базой данных. Именование классов, свойств, переменных надлежащим образом я считаю одной из самых сложных частей работы, но это облегчает нашу жизнь.
Btw. Избегайте передачи всего контейнера в качестве служебного параметра:
arguments: ['@service_container',
потому что это слишком дорогостоящие ресурсы.