Doctrine — подкаталог вложенных сущностей / пространства имен

#php #doctrine-orm #doctrine

#php #doctrine-orm #доктрина

Вопрос:

Я довольно долго искал ответ на этот вопрос, и я просто не получаю ничего, что звучит разумно прямо сейчас. Итак, вот дилемма…

У меня есть Entity каталог со структурой вложенности. Это просто работает намного лучше для нашей организации. Итак, у нас может быть что-то вроде:

 ./Entity
./Entity/User
./Entity/User.php
./Entity/User/Type
./Entity/User/Type/Administrator.php
./Entity/User/Type/Editor.php

  

Итак, в основном 2 типа пользователей. В этом случае пространство имен будет следовать за PSR4. В приведенном выше случае у нас будут следующие файлы:

User.php

 namespace Entity;

use DoctrineORMMapping as ORM;

/**
 * User Entity
 *
 * @ORMEntity
 * @ORMInheritanceType("SINGLE_TABLE")
 * @ORMDiscriminatorColumn(name="user_key", type="string")
 * @ORMDiscriminatorMap({
 *      "administrator" = "EntityUserTypeAdministrator",
 *      "editor" = "EntityUserTypeEditor",
 * })
 *
 * @ORMTable
 */
abstract class User
  

Administrator.php

 namespace EntityUserType;

use DoctrineORMMapping as ORM;
use EntityUser;

/**
 * Administrator Entity
 *
 * @ORMEntity
 */
class Administrator extends User
  

И при этом я получаю следующую ошибку:

 DoctrineORMMappingMappingException: Entity class 'EntityUserTypeAdministrator' used in the discriminator map of class 'EntityUser' does not exist.

/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php:479
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:2875
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:2847
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php:265
/srv/www/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php:79
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:155
/srv/www/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php:306
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:82
/srv/www/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php:185
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:288
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1764
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1737
/srv/www/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:610
  

Итак, как мне зарегистрировать это пространство имен или в чем здесь проблема? Я попытался явно передать путь к сущности AnnotationDriver , который используется для сопоставления.

Я не ищу здесь решение конфигурации Symfony yml. Я также не ищу 2 экземпляра менеджера сущностей. Мне нужен один диспетчер сущностей, и я хочу, чтобы эти пространства имен поддерживались.

При создании прокси-классов я подтвердил, что они правильно распознают вложенные объекты пространства имен и правильно генерируют прокси-классы.

Обновить:

Кажется очевидным, что прокси-классы генерируются с дополнительным пространством имен, поскольку фактические сущности структурированы. Итак, я думаю, это выглядит правильно.

 // Normal
namespace EntityProxy__CG__Entity;
// Nested
namespace EntityProxy__CG__EntityUserType;
  

Однако эти файлы прокси-классов находятся на том же уровне, что и все другие прокси-классы — вложенности нет.

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

Комментарии:

1. Вы говорите, что вам не нужно решение на основе Symfony, но префикс ORM происходит от Symfony. При использовании готового Doctrine вы обычно просто используете @Entity вместо @ORMEntity . Но я подозреваю, что у вас простая проблема с отображением пространства имен PSR4. Использование Entity в качестве префикса корневого пространства имен немного странно. Обычно у вас будет префикс пространства имен для всего проекта, который, в свою очередь, становится частью вашего сопоставления PSR4. Я тестирую ваш код, используя простой загрузочный файл doctrine, и он работает так, как ожидалось. Я могу опубликовать свой код в качестве ответа, если хотите.

2. Если нет, то покажите свой bootstrap.php код и раздел psr4 composer.json. Не забудьте запустить ‘composer dump-автозагрузка’ после внесения любых изменений psr4 в composer.json.

3. @Cerad спасибо за информацию. Пространство имен здесь используется только для примера, это весь псевдокод. Вы предполагаете, что то, что описано в этом выпуске, возможно и поддерживается Doctrine? Псевдоним ORM use просто позволяет использовать меньше инструкций use. В этом нет ничего по сути «Symfony». В Composer нет проблем с автозагрузкой. Существуют службы, расположенные в аналогичных вложенных каталогах, которые хорошо работают там и с компонентом DI Symonfy. К сожалению, начальная загрузка для менеджера сущностей довольно большая и сложная. Но, если это должно работать…

4. Проблема решена. Перед именем файла был добавлен начальный (пробел). вздох

5. Рад, что у вас все получилось. Меня всегда немного смущало (для меня), что примеры в Doctrine docs редко используют ORM, в то время как Symfony используют. И если вы возьмете один из примеров Doctrine и добавите оператор use, он все равно не сработает. Вам нужно использовать определенный читатель аннотаций. Просто одна из этих вещей.