Details
Description
Example
/** * @Entity * @Table( * name="eav_attribute", * uniqueConstraints={ * @UniqueConstraint(columns={"core_project_id", "name"}) * } * ) * @InheritanceType( * "SINGLE_TABLE" * ) * @DiscriminatorColumn( * name="datatype", * type="string" * ) * @DiscriminatorMap({ * "datetime"="AttributeDatetime", * "decimal"="AttributeDecimal", * "int"="AttributeInt", * "string"="AttributeString", * "text"="AttributeText" * }) */ abstract class AbstractAttribute { // ... /** * @Column(type="string") */ protected $name; /** * @Column(type="boolean") */ protected $is_unique; // ... } /** * @Entity */ class AttributeDatetime extends AbstractAttribute { }
Expected SQL-dump:
name VARCHAR(255) NOT NULL, is_unique TINYINT(1) NOT NULL,
SQL-dump created by SchemaTool:
name VARCHAR(255) DEFAULT NULL, is_unique TINYINT(1) DEFAULT NULL,
This behaviour is problematic, especially for columns which are part of a unique constraint.
Reason:
SchemaTool doesn't really check for inherited fields in STI sub classes in method getSchemaFromMetadata() and passes all fields (incl. the inherited) to method _gatherColumn() where finally the column definition of the parent class will be overwritten.
Doctrine\ORM\Tools\SchemaTool
private function _gatherColumn($class, array $mapping, $table) { // Lines 309 - 311 if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0) { $options['notnull'] = false; } }
A quick fix:
Change that if-clause above to
if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0 && ! isset($mapping['inherited'])) {
Better fix:
Only pass not inherited fields to the _gatherColumn() method, as done with CTI sub classes.
Fixed