Gadelkareem
Gadelkareem

Reputation: 1087

Doctrine2 Multiple level single table inheritance ( Unknown column )

I am not sure if this is a bug or something wrong in my code:

<?php
namespace MyProject\Model;

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({
 *      "customer" = "Customer", 
 *      "projectManager" = "ProjectManager", 
 *      "developer" = "Developer"
 * })
 */
abstract class Person
{
    // ...
}

/**
 * @Entity
 */
class Customer extends Person
{
    // ...
}

/**
 * @Entity
 */
abstract class Employee extends Person
{
    /**
     * @var boolean
     * @Column(name="retired", type="boolean", nullable=true)
     */
    protected $retired;
}

/**
 * @Entity
 */
class ProjectManager extends Employee
{
    // ...
}

/**
 * @Entity
 */
class Developer extends Employee
{
    // ...
}

When trying to update the database app/console doctrine:schema:update --force Doctrine ignores Employee::retired attribute and the application would result in error: Unknown column 'retired'

If I created the column manually everything is working as expected. Moreover, this only happens with single table so if I switch to class table inheritance then the column is created on schema update.

Upvotes: 1

Views: 835

Answers (2)

user228395
user228395

Reputation: 1176

You don't have to map your in-between abstract entities in the discriminator map of your root entity for this to work. Just do not make it an @Entity, but an @MappedSuperclass.

In your case Employee should be a @MappedSuperclass and everything extending Employee an @Entity represented in the map.

Upvotes: 0

Blacksad
Blacksad

Reputation: 1280

You cannot 'jump' to lowest level inheritance, you have to describe each level.

At leat it works with @InheritanceType("JOINED"), I guess it is the same with SINGLE_TABLE.

<?php
namespace MyProject\Model;

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({
 *      "customer"       = "Customer", 
 *      "employee"       = "Employee",
 *      "projectManager" = "ProjectManager", 
 *      "developer"      = "Developer"
 * })
 */
abstract class Person
{
    // ...
}

/**
 * @Entity
 */
class Customer extends Person
{
    // ...
}

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({
 *      "employee"       = "Employee", 
 *      "projectManager" = "ProjectManager", 
 *      "developer"      = "Developer"
 * })
 */
abstract class Employee extends Person
{
    /**
     * @var boolean
     * @Column(name="retired", type="boolean", nullable=true)
     */
    protected $retired;
}

/**
 * @Entity
 */
class ProjectManager extends Employee
{
    // ...
}

/**
 * @Entity
 */
class Developer extends Employee
{
    // ...
}

Upvotes: 1

Related Questions