Can a single table inheritance entity extend a class table inheritance entity?

virtualize picture virtualize · Dec 3, 2013 · Viewed 7.6k times · Source

This is my base/parent entity, setup so its children are using their own tables.

/**
 * @ORM\Entity
 * @ORM\Table(name="layer_object")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"service"="Service", "aircraft"="Aircraft", ...})
 */
class LayerObject {}

Aircraft entity. A simple child that is doing well

/**
 * @ORM\Entity
 * @ORM\Table(name="aircraft")
 */
class Aircraft extends LayerObject

Service entity. A complex child, that itself is using single table inheritance.

/**
 * @ORM\Entity
 * @ORM\Table(name="service")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"ground"="Ground", "onboard"="Onboard"})
 */
class Service extends LayerObject {}

A child of the Service entity

/**
 * @ORM\Entity
 */
class Ground extends Service {}


app/console doctrine:schema:validate finds no errors but app/console doctrine:schema:update --force just won't generate the 'service' table, the one that should use single table inheritance. Seems like the service entity definition is simply ignored.

Sure I could create the SQL for this table by hand, but the application will grow and at some point I will need to use migrations.

Could anyone point me in some direction? Thanks.

Found a duplicate, but there are no answers so far, see: Doctrine 2 multiple level inheritance

Edit:
When I use class table inheritance for the 2nd level too (@ORM\InheritanceType("JOINED") for the Service entity) it works pretty well. See: Doctrine2 Multiple level inheritance

Answer

Nicolai Fröhlich picture Nicolai Fröhlich · Dec 4, 2013

What you're trying to achieve is not possible with pure mapping.

The documentation for Class Table Inheritance and Single Table Inheritance clearly state:

The @InheritanceType, @DiscriminatorColumn and @DiscriminatorMap must be specified on the topmost class that is part of the mapped entity hierarchy.

You might be able to make this work by implementing a subscriber to the loadClassMetaData event that changes the inheritance-type dynamically (i.e. based on annotations on of the child entities).

Some further inspiration can be found in this article.