1

I want to implement the Class Table Inheritance:

/**
 * Foo
 *
 * @ORM\Table(name="foos", ...)
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "bar" = "Bar",
 *     "buz" = "Buz"
 * })
 */
abstract class Foo
{
    ...
}

Since I run the "code first" approach, the database is generated by Doctrine:

$ bin/console doctrine:migrations:diff
$ bin/console doctrine:migrations:migrate

The discriminator column foos.type gets the type VARCHAR(255). I want it to get an ENUM instead.

How to define the annotation for the entity class for getting an ENUM discriminator?

automatix
  • 14,018
  • 26
  • 105
  • 230
  • Once again, editing the schema file is the only way I found. Does not really matter. You have no access to it via the orm anyways. – Cerad Jun 19 '18 at 17:52
  • Check out: https://stackoverflow.com/questions/3579079/how-can-you-represent-inheritance-in-a-database – Rick James Oct 12 '18 at 18:56

2 Answers2

1

It works with columnDefinition="ENUM('bar', 'buz')":

/**
 * Foo
 *
 * @ORM\Table(name="foos", ...)
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string", columnDefinition="ENUM('bar', 'buz')")
 * @ORM\DiscriminatorMap({
 *     "bar" = "Bar",
 *     "buz" = "Buz"
 * })
 */
abstract class Foo
{
    ...
}

Unfortunately it causes an annoying side effect (s. also here): The migration mechanism of Doctrine seems to handle ENUMs incorrectly. The doctrine:migrations:diff command creates a migration like this:

final class Version20180619205625 extends AbstractMigration
{
    public function up(Schema $schema) : void
    {
        $this->addSql('ALTER TABLE foos CHANGE type `type` ENUM(\'bar\', \'buz\')');
    }

    public function down(Schema $schema) : void
    {
        $this->addSql('ALTER TABLE tasks CHANGE `type` type VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci');
    }
}

I execute it, the type column become an ENUM. But a new executing of doctrine:migrations:diff creates a migration with the same content again... Means, Doctrine "thinks", the column is still VARCHAR.

automatix
  • 14,018
  • 26
  • 105
  • 230
1

Bit late answer, but the solution is to register a custom mapping type which will actually use ENUM on database side. Most simply:

class YourType extends Type
{
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
    {
        return 'ENUM(\'one\', \'two\')';
    }
}

register it in your Doctrine config under some your_type name and use:

 @ORM\DiscriminatorColumn(name="type", type="your_type")

This field will be NOT NULL by default. In case of mysql, it'll use first value from ENUM as default, like a "implicit default"

Wojciechem
  • 51
  • 6