How To Use Doctrine Fixtures with Discriminator Maps

my-pet-cat-entityThis is one of those issues where over-thinking the problem is usually the cause of your problems.

When using a discriminator map, for example, if using Single Table Inheritance, your ‘mapped entity’ will be extending a base entity.

For example, we might have the Pet base entity, and the PetCat extended entity.

Inside our fixture, we might do something like this:

namespace MCM\PetBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;

use MCM\PetBundle\Entity\Pet;

class LoadPetCatData extends AbstractFixture implements OrderedFixtureInterface
{
    /**
     * {@inheritDoc}
     */
    public function load(ObjectManager $manager)
    {
        $cat = new Pet();
        
        $cat->setName('Friendly Cat');
        $cat->setFood('Whiskers');

        $manager->persist($cat);

        $manager->flush();
    }

    /**
    * {@inheritDoc}
    */
    public function getOrder()
    {
        return 3; // the order in which fixtures will be loaded
    }
}

But this will throw up an error, as when doctrine tries to execute your SQL, it will be missing the discriminator mapping.

Why?

Well, above on line 7 we are using: use MCM\PetBundle\Entity\Pet;, but we need to use the extended class / entity, so we should be using: use MCM\PetBundle\Entity\PetCat;.

Then instead of instantiating the base class on line 16: $cat = new Pet();, we just instantiate: $cat = new PetCat();, and all our troubles seem so far away.

Hopefully that helps – I found nothing on Google about this when I looked, and it had me scratching my head as to why. But the answer is pretty straightforward once you stop over thinking it.