Доктрина 2, как правильно отображать многоуровневое наследование

У меня есть многоуровневая доктрина наследования, подобная этой:

/**
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({"customer" = "CustomerUser",
 * "admin" = "AdminUser", "stock" = "StockUser"})
 */
abstract class User { ... }

/** @ORM\Entity */
abstract class EmployeeUser extends User { ... }

/** @ORM\Entity */
class AdminUser extends EmployeeUser { ... }

/** @ORM\Entity */
class StockUser extends EmployeeUser { ... }

Однако это не работает, поля EmployeeUser не считываются из базы данных и не сохраняются.

Я обнаружил, что это работает, когда я указываю карту дискриминатора следующим образом:

 * @ORM\DiscriminatorMap({"customer" = "CustomerUser",
 * "admin" = "AdminUser", "stock" = "StockUser", "EmployeeUser"})

он начинает работать таким образом (нет необходимости указывать ключ дискриминатора для EmployeeUser - поскольку он абстрактен и никогда не будет инстанцирован), но

Мне не нравится, когда происходит волшебство, которого я недостаточно понимаю :) поэтому мой вопрос: правильное ли это решение? Просто сообщить Doctrine таким образом, что этот класс каким-то образом включен в иерархию наследования? Или это нужно сделать как-то иначе?

Я не нашел упоминания о том, как выполнять многоуровневое наследование классов сущностей в документах Doctrine.


person amik    schedule 18.02.2016    source источник
comment
Это выглядит хорошо. Что, если вы определите , "employee" = "EmployeeUser" в DiscriminatorMap? Возможно, Doctrine требует дискриминатора для каждой дочерней сущности. Во всяком случае, я не знаю, поддерживается ли наследование с несколькими уровнями, разве вы не можете использовать только 2 уровня?   -  person A.L    schedule 20.02.2016


Ответы (1)


у меня такая же ситуация. Мне нужно более одного уровня наследования. Это в вашем случае ожидаемое поведение, вам нужно перечислить все сопоставленные классы в DiscriminatorMap.

В моем случае нет этой карты, потому что я использую собственное преобразование ClassName для ввода ключа, и оно работает для классов на всех уровнях наследования.

abstract ClassA
abstract ClassB extends ClassA
   - protected someName
ClassC extends ClassB

Когда я сохраняю объект ClassC, у меня сохраняется это свойство someName. Вы можете попробовать себя без дискриминационной карты и увидеть, что все классы сопоставлены и сохранены.

ИЗМЕНИТЬ:

Еще одна вещь, если вы хотите избежать многоуровневого наследования, вы всегда можете использовать для этого trait. Просто сгруппируйте реквизиты для черты и добавьте их в сущность. В пакете DoctrineBehaviors есть хороший пример использования трейта. Он используется для импорта дополнительных возможностей в такие объекты, как blamable, loggable и т. д.

person Nikola Loncar    schedule 21.03.2016
comment
Спасибо, я не знал, что можно не указывать карту дискриминатора. Это, конечно, самое удобное решение. - person amik; 11.04.2016