Robin K
Robin K
Jul 10, 2017 · 2 min read

Not sure what happened to my account (RKeet in prev comments) but thought to place update here as this article is referenced a lot still on Stackoverflow with regards to Discriminators with Doctrine2.

To now use Discriminators using the “Class Table Inheritance” method (as opposed to “Single Table Inheritance”) is to NOT DECLARE a Discriminator Map! (Not sure if this will also work for STI…)

I found an old ticket on Github that explains the same issue as this article and which many people still have, that declaring on the parent makes no sense. After reading through that, I dove into the code and re-read the docs, carefully.

Also, if you’re reeeeaaally careful when reading the docs, it says this is possible, by not saying it.

Quoting:

Things to note:

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

The @DiscriminatorMap specifies which values of the discriminator column identify a row as being of which type. In the case above a value of “person” identifies a row as being of type Person and “employee” identifies a row as being of type Employee.

The names of the classes in the discriminator map do not need to be fully qualified if the classes are contained in the same namespace as the entity class on which the discriminator map is applied.

If no discriminator map is provided, then the map is generated automatically. The automatically generated discriminator map contains the lowercase short name of each class as key.

So, if you were to stretch your classes across several modules (as I assume that’s why you would be reading this), do not declare a discriminator map!

I’ll leave you with an example below:

<?php
namespace My\Namespace\Entity;

/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
*/
class Person
{
// ...
}
<?php
namespace My\Other\Namespace\Entity;
/** @Entity */
class Employee extends \My\Namespace\Entity\Person
{
// ...
}

When you use the doctrine CLI command to check your entities, you’ll find this is correct.

Also, check that it fully works by using the entity checking command:

./vendor/bin/doctrine-module orm:mapping:describe “\My\Namespace\Entity”

Near the top of the response of that command will be this line:

| Discriminator map | {“person”:”My\\Namespace\\Entity\\Person”,”employee”:”My\\Other\\Namespace\\Entity\\Employee”}

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade