tl; dr Как метод getManagerForClass()
обнаруживает, какой менеджер getManagerForClass()
является правильным для определенного класса?
Я создал общий контроллер, который должен иметь возможность обрабатывать основные действия для разных объектов. У меня также есть подключения к двум различным базам данных, поэтому я использую два менеджера сущностей.
В моем контроллере я пытаюсь использовать метод getManagerForClass () Doctrine, чтобы найти, какой менеджер использовать для каждого класса, как описано в этом блоге, и этот ответ SO .
Но этот метод, похоже, не отличает двух моих менеджеров сущностей и просто возвращает первый в конфигурации.
Мои действия с контроллером начинаются следующим образом:
public function indexAction($namespace, $entityName) { $classFullName = "AppBundle:$namespace\\$entityName"; $em = $this->getDoctrine()->getManagerForClass($classFullName);
Это моя конфигурация Doctrine:
dbal: default_connection: postgres connections: postgres: driver: pdo_pgsql host: "%database_host%" port: "%database_port%" dbname: "%database_name%" user: "%database_user%" password: "%database_password%" charset: UTF8 oracle: driver: oci8 host: "%oracle_host%" port: "%oracle_port%" dbname: "%oracle_name%" user: "%oracle_user%" password: "%oracle_password%" charset: UTF8 orm: auto_generate_proxy_classes: true entity_managers: postgres: connection: postgres mappings: AppBundle: type: annotation dir: Entity\Postgres oracle: connection: oracle mappings: AppBundle: type: annotation dir: Entity\Oracle
И моя структура папок выглядит следующим образом:
AppBundle |___Controller | |___EntityController.php | |___Entity |___Postgres | |___SomePostgresBasedEntity.php | |___Oracle |___SomeOracleBasedEntity.php
Теперь я не знаю точно, как работает этот метод, и как он должен знать о сопоставлении, если не через конфигурацию. Но если я так называю это, например:
$em = $this->getDoctrine()->getManagerForClass("AppBundle:Oracle\\SomeOracleBasedEntity");
… Я получаю менеджер объектов для Postgres.
Но если я просто переключаю конфигурацию менеджера сущностей, сначала ставя одну для oracle, предыдущий вызов работает, но следующее:
$em = $this->getDoctrine()->getManagerForClass("AppBundle:Postgres\\SomePostgresBasedEntity");
getManagerForClass()
циклически проходит через каждый менеджер и для каждого из них, проверяет, является ли класс «не-переходным»:
foreach ($this->managers as $id) { $manager = $this->getService($id); if (!$manager->getMetadataFactory()->isTransient($class)) { return $manager; } }
Это доходит до AnnotationDriver->isTransient()
. Здесь в документе говорится следующее:
Класс не является переходным, если он аннотируется аннотацией из AnnotationDriver :: entityAnnotationClasses.
@Entity
похоже, является одной из тех аннотаций, которая делает класс не-переходным. Но тогда, как может любое из моих сущностей быть преходящим вообще? Как водитель может отличить сущность, принадлежащую определенному менеджеру, основываясь исключительно на своих аннотациях? Я, должно быть, пропустил что-то в классах более высокого уровня.
Метод работает при использовании сопоставлений yml
.
Я как бы ожидал такого поведения. Разница исходит из реализаций метода isTransient () в разных драйверах. Реализация isTransient FileDriver возвращает true
если файл метаданных существует в каталоге dir:
конфигурации конфигурации.
Я бы ожидал, что AnnotationDriver будет искать аннотации только в объектах, содержащихся в указанном каталоге dir:
но, похоже, этот параметр игнорирует. Или я должен использовать другой?