You are browsing a version that has not yet been released. |
Inheritance Mapping
Doctrine supports two approaches to inheritance:
- Single collection inheritance, where all classes in the hierarchy are stored in the same collection and a discriminator field identifies each document type.
- Sharing common fields across document classes stored in different collections, using PHP inheritance or traits.
Single Collection Inheritance
In single collection inheritance, each document is stored in a single collection and a discriminator field is used to distinguish one document type from another.
Simple example:
<?phpnamespace Documents;#[Document]#[InheritanceType('SINGLE_COLLECTION')]#[DiscriminatorField('type')]#[DiscriminatorMap(['person' => Person::class, 'employee' => Employee::class])]class Person{ // ...}#[Document]class Employee extends Person{ // ...}
The discriminator value allows Doctrine to infer the class name to instantiate when hydrating a document. If a discriminator map is used, the discriminator value will be used to look up the class name in the map.
Now, if we query for a Person and its discriminator value is employee, we
would get an Employee instance back:
<?php$employee = new Employee();// ...$dm->persist($employee);$dm->flush();$employee = $dm->find(Person::class, $employee->getId()); // instanceof Employee
Even though we queried for a Person, Doctrine will know to return an Employee instance because of the discriminator map!
If your document structure has changed and you've added discriminators after already having a bunch of documents, you can specify a default value for the discriminator field:
<?phpnamespace Documents;#[Document]#[InheritanceType('SINGLE_COLLECTION')]#[DiscriminatorField('type')]#[DiscriminatorMap(['person' => Person::class, 'employee' => Employee::class])]#[DefaultDiscriminatorValue('person')]class Person{ // ...}#[Document]class Employee extends Person{ // ...}
Sharing Common Fields
To share common fields across multiple document classes stored in different collections, use a PHP abstract parent class or a trait. ODM reads field mappings from all properties of a class through reflection, whether they are declared in the class itself, a parent class, or a trait.
Each class is stored in its own collection. Unlike single collection inheritance, there is no discriminator field and documents are not polymorphically queryable across classes.
Abstract parent class
<?phpnamespace Documents;abstract class BaseDocument{ #[Field] private string $createdBy;}#[Document(collection: 'articles')]class Article extends BaseDocument{ // inherits $createdBy}#[Document(collection: 'comments')]class Comment extends BaseDocument{ // inherits $createdBy}
PHP trait
<?phpnamespace Documents;trait Timestamps{ #[Field] private DateTimeImmutable $createdAt; #[Field] private DateTimeImmutable $updatedAt;}#[Document(collection: 'articles')]class Article{ use Timestamps;}#[Document(collection: 'comments')]class Comment{ use Timestamps;}
Mapped Superclass
When using XML mapping, each class requires its own mapping file. To share
fields from a parent class, declare it as a mapped-superclass so the driver
knows to load its mapping file:
<?phpnamespace Documents;#[MappedSuperclass]abstract class BaseDocument{ #[Field] private string $createdBy;}
|
A mapped superclass cannot be a document and is not queryable. |
