3

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

Talus
  • 754
  • 7
  • 18

2 Answers2

0

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
nakashu
  • 1,058
  • 12
  • 21
  • Wouldn't there be a `SpecialImage` table created then ? This is what I want to avoid – Talus Jun 10 '15 at 18:10
  • moreover, I want to discriminate against a column that is specific to the `Image` (or `AbstractVideo` in my case) entity – Talus Jun 10 '15 at 18:10
  • you are right. It would create new tables. I was confused because i saw you got there also "JOINED" inheritence type. it seems altho you are mixing two Ingeritencetypes , JOINED and SINGLETABLE. My guess is that can be the problem. – nakashu Jun 10 '15 at 18:49
  • Yup, I also thought so, but a multiple table solution (with only joined_tables) is not what I'm looking for, as for the sub classes for Video are just dependent on a field, the other ones are the same basically. The joined is needed for media / video / document because they do have different data, and also the discriminator column is not the same between the two layers of inheritance (the joined one depends on the `type`, while the other one on the `provider`) – Talus Jun 10 '15 at 19:48
0

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 ...
}
Community
  • 1
  • 1
Talus
  • 754
  • 7
  • 18