Судя по нашим комментариям, я вижу ваше недоумение. Поскольку документы обрабатывают и MappedSuperclass, и Discriminator на одной странице, я думаю, вы перепутали их использование в своей голове. Надеюсь, это поможет вам:
MappedSuperclass
предоставляет свойства / значения по умолчанию для многократного использования, но он никогда не может быть сущностью сам по себе. Это сопоставимо с классами PHP abstract
(которые не могут быть созданы сами по себе)
- Дискриминатор дает возможность расширить сущность, сделав ее другой сущностью. Например, наличие
Person
Entity дает вам 1 Entity. Этот объект может быть расширен, например, на Worker
и Manager
.
Хорошим вариантом использования MappedSuperclass
будет AbstractEntity
. Каждой сущности нужен идентификатор, уникальный идентификатор. Это также дает вам что-то общее, что можно проверить в Listeners и тому подобном. Итак, вперед и создайте:
/**
* @ORM\MappedSuperclass
*/
abstract class AbstractEntity
{
/**
* @var int
* @ORM\Id
* @ORM\Column(name="id", type="integer", options={"unsigned":true})
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
// getter / setter
}
Видите, как это объявлено как abstract
, так и MappedSuperclass
?
Это связано с тем, что ни один из (abstract class
и MappedSuperclass
) не может быть создан сам по себе. Вы не можете делать $entity = new AbstractEntity()
, потому что это abstract
класс PHP. Doctrine также не будет создавать отдельную таблицу для AbstractEntity
.
Затем создайте Person
:
/**
* @ORM\Entity
* @ORM\Table(name="persons")
*
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
*/
class Person extends AbstractEntity
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
// getter / setter
}
Вышеупомянутый Person
, Entity настроен для Наследование таблицы классов через JOINED
тип наследования. Это означает, что на уровне базы данных таблица persons
будет отделена от любых столбцов, добавленных другими сущностями, расширяя Person
.
Обратите внимание, как я не объявил DiscriminatorMap
. Ниже из документов, выделенных мной жирным шрифтом:
На заметку:
- @InheritanceType, @DiscriminatorColumn и @DiscriminatorMap должны быть указаны в самом верхнем классе, который является частью иерархии сопоставленных сущностей.
- @DiscriminatorMap указывает, какие значения столбца дискриминатора идентифицируют строку как принадлежащую к какому типу. В приведенном выше случае значение person идентифицирует строку как имеющую тип Person, а employee определяет строку как имеющую тип Employee.
- Имена классов в карте дискриминатора не должны быть полностью квалифицированы, если классы содержатся в том же пространстве имен, что и класс сущности, к которому применяется карта дискриминатора.
- Если карта дискриминатора не указана, она создается автоматически. Автоматически созданная карта дискриминатора содержит краткое имя каждого класса в нижнем регистре в качестве ключа.
Теперь давайте создадим Worker
:
/**
* @ORM\Entity
* @ORM\Table(name="workers")
*/
class Worker extends Person
{
/**
* @var int
* @ORM\Column(name="worker_id", type="integer", length=11, nullable=false)
*/
protected $workerId;
// getter / setter
}
Итак, теперь у нас есть:
- MappedSuperclass:
AbstractEntity
- не автономный объект
- Дискриминация:
Person
- является отдельной организацией
- нормальный:
Worker
- расширяется Person
На заметку:
- Невозможно создать экземпляр MappedSuperclass. Таким образом: вы не можете создавать ссылки / отношения с ним. Сравним с PHP
abstract class
- Дискриминируемая сущность - это такая сущность, которая также стоит особняком и может использоваться как обычная сущность. Вы можете создавать отношения с ним и от него без проблем
- Сущность, расширяющая Дискриминируемую Сущность, является экземпляром обоих. В приведенном выше коде истинны оба значения:
$worker instanceof Worker
и $worker instanceof Person
, потому что Worker
расширяет Person
. Однако $person instanceof Worker
будет false
!
$workerId = $person->getWorkerId() // generates "method does not exist" fatal
$workerId = $worker->getWorkerId() // generates integer value
Надеюсь, вам удалось прояснить ситуацию. Если нет, не стесняйтесь спрашивать.
person
rkeet
schedule
06.02.2019
//other fields mapping
. - person user1032531   schedule 05.02.2019MappedSuperClass
. (Ямл:type: mappedSuperclass
, XML:<mapped-superclass name="MyProject\Model\User">
) - person rkeet   schedule 05.02.2019@OneToOne(targetEntity="MappedSuperclassRelated1")
и@JoinColumn(name="related1_id", referencedColumnName="id")
, конечно, это не так уж сложно преобразовать. Что еще более важно, это не объясняет, какEntitySubClass
знает, что это связано сMappedSuperclassBase
, и это та часть, над которой я борюсь. Спасибо - person user1032531   schedule 05.02.2019Worker
расширяетPerson
(суперкласс), то у вас есть 1 Entity: Worker. Создание отношения кWorker
(т.е. отPaycheck
), ссылки только на Worker. СуперклассPerson
просто создает базовый набор свойств / значений по умолчанию, которые используются в Worker. - person rkeet   schedule 06.02.2019MappedSuperClass
с классомDiscriminator
. Первый предоставляет свойства / значения по умолчанию для дочернего класса, но никогда не является сущностью сам по себе. Последняя, выделенная сущность, представляет собой отдельный класс. - person rkeet   schedule 06.02.2019