Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-966

SchemaTool does not check for inherited fields in STI sub-classes and overwrites their column definitions to DEFAULT NULL

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.0
    • Fix Version/s: 2.0.1, 2.1
    • Component/s: Tools
    • Security Level: All
    • Labels:
      None

      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.

        Activity

        Hide
        Benjamin Eberlei added a comment -

        Fixed

        Show
        Benjamin Eberlei added a comment - Fixed
        Hide
        ayhan added a comment -

        Wow, that was fast!

        Show
        ayhan added a comment - Wow, that was fast!

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            ayhan
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: