Multiple level of different kind of inheritance

167 views Asked by At

For my project, I'm trying to use the inheritance feature of Doctrine. I need to represent medias (through different tables : one table for uploaded documents, one for linked videos, ... and so on).

But, the videos can vary from provider to provider (such as Youtube, Dailymotion, you name it). So, I was thinking of doing another inheritance, proper to the Video table, through a SINGLE_TABLE inheritance.

But, when I declare my entities, it seems that if I add the SINGLE_TABLE inheritance annotation on the AbstractVideo entity, which extends the AbstractMedia Entity, the Video table is never created (nor detected). Here is a snippet of these two entities :

<?php
namespace Acme\Demo\Entity;

use Datetime;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="Media")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 */
abstract class AbstractMedia
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    // some other fields
}

/**
 * @ORM\Entity
 * @ORM\Table(name="Video")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="provider", type="string")
 * @ORM\DiscriminatorMap({})
 */
abstract class AbstractVideo extends AbstractMedia
{
    /** @ORM\Column(type="string") */
    private $name;

    // some other fields
}

I already tried to have a mapped entity to a Foo entity, extending the AbstractVideo, but then when I try to persist something, it says that it is not a valid entity.

Any ideas, or should I really avoid such deep inheritance ? Thanks

2

There are 2 answers

0
Talus On BEST ANSWER

As @OCramius said in a comment to my question, this is not supported by Doctrine ORM. So to do what I wanted to do, I will store a value object in the data property of my object, storing the property of "child classes" instead of having deep different kind of inheritance.

<?php
class Video extends AbstractMedia
{
    // returns the value object youtube, dailymotion, ... etc
    public function getData();    
}

class Youtube
{
   //public function ...
}

class Dailymotion
{
   // public funciton ...
}
4
nakashu On

Not really sure if this is exactly what you need, but this is from a production code I use.

We inherit the file, with other entities, and those are also inherited. The important part is to add the inheriting(extending) entities to disciminator map.

/**
 * File
 *
 * @ORM\Table(name = "file")
 * @ORM\Entity(repositoryClass="Living\ApiBundle\Entity\File\FileRepository")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string", length=64)
 * @ORM\DiscriminatorMap({
 *      "file"  = "Something\Entity\File\File",
 *      "image" = "Something\Entity\Image\Image",
 *      "specialImage" = "Something\Entity\Image\SpecialImage",
 * })
 */
class File implements FileEntityInterface

.....

/**
 * ImageFile
 *
 * @ORM\Table(name="image")
 * @ORM\Entity(repositoryClass="Living\ApiBundle\Entity\Image\ImageRepository")
 */
class Image extends File implements ImageEntityInterface