2010-10-14 12 views
5

J'utilise Doctrine2 pour gérer mon modèle ci-dessous: Il y a un concept abstrait Content avec un motif composite Gallery, également un concept abstrait Media dont Video et Image inherits.multiples niveaux de discrimination tout en utilisant Doctrine2

Mon choix était d'ajouter discriminateurs à Content et Media tables afin de faire la différence entre Gallery, Video et Image. Content utilise JOIN inheritance et Media utilise SINGLE_TABLE inheritance. Comme je cours doctrine orm:schema-tool:create --dump-sql, le tableau Media est la duplication des colonnes de l'Content un

C'est la sortie de la commande:

CREATE TABLE Content (id INT AUTO_INCREMENT NOT NULL, container_id INT DEFAULT NULL, creationDate DATETIME NOT NULL, publicationDate DATETIME DEFAULT NULL, isGallery TINYINT(1) NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB; 
CREATE TABLE Media (id INT AUTO_INCREMENT NOT NULL, creationDate DATETIME NOT NULL, publicationDate DATETIME DEFAULT NULL, width INT NOT NULL, height INT NOT NULL, isImage TINYINT(1) NOT NULL, bitrate INT NOT NULL, duration INT NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB; 
CREATE TABLE Gallery (id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB; 
ALTER TABLE Content ADD FOREIGN KEY (container_id) REFERENCES Gallery(id); 
ALTER TABLE Gallery ADD FOREIGN KEY (id) REFERENCES Content(id) ON DELETE CASCADE 

Voici mes classes et annotations:

content.php

/** @Entity 
* @InheritanceType("JOINED") 
* @DiscriminatorColumn(name="isGallery", type="boolean") 
* @DiscriminatorMap({ 
*  0 = "Media", 
*  1 = "Gallery" 
* }) 
*/ 
abstract class Content 
{ 
    /** @Id @GeneratedValue @Column(type="integer") */ 
    private $id; 
    /** @Column(type="datetime") */ 
    private $creationDate; 
    /** @Column(type="datetime", nullable="true") */ 
    private $publicationDate; 
    /** @ManyToOne(targetEntity="Gallery", inversedBy="contents") */ 
    private $container; 
} 

media.php

/** @Entity 
* @InheritanceType("SINGLE_TABLE") 
* @DiscriminatorColumn(name="isImage", type="boolean") 
* @DiscriminatorMap({ 
*  0 = "Video", 
*  1 = "Image" 
* }) 
*/ 
abstract class Media extends Content 
{ 
    /** @Column(type="integer") */ 
    private $width; 
    /** @Column(type="integer") */ 
    private $height; 
} 

gallery.php

/** @Entity */ 
class Gallery extends Content 
{ 
    /** @OneToMany(targetEntity="Content", mappedBy="container") */ 
    private $contents; 
} 

video.php

/** @Entity */ 
class Video extends Media 
{ 
    /** @Column(type="integer") */ 
    private $bitrate; 
    /** @Column(type="integer") */ 
    private $duration; 
} 

Image.php

/** @Entity */ 
class Image extends Media 
{ 
} 

Je demande: C'est le comportement correct? Ne doit pas Media avoir seulement les champs id, width et height, plus bitrate et duration de Video?

De plus, y a-t-il un moyen de se débarrasser de la table inutile de Gallery?

J'espère que je l'ai fait assez clair, cependant, n'hésitez pas à demander. Merci d'avance.

MISE À JOUR: Aucun moyen. J'ai essayé de trouver un exemple encore plus simple ne montrant pas ce comportement, mais je n'en ai trouvé aucun.

Des suggestions? Serait-ce un bug dans Doctrine 2 ou il me manque une solution plus simple?

Répondre

5

Je réponds moi-même à ma question en espérant que cela aidera quelqu'un un jour.

J'ai ouvert un bug report in github for doctrine2 avec cette question et la réponse est assez claire: Ceci n'est pas supporté.

MISE À JOUR 2013/07/27

Je viens d'essayer cela avec la doctrine et il fonctionne 2.3.4 comme prévu.: D

+0

Je suis avec la doctrine 2.3.4 aussi, mais le comportement ne fonctionne pas. La table Media n'est pas créée, avez-vous des retours? –

+0

Vous pouvez voir mon test ici: https://github.com/paulandrieux/MultipleInheritanceSandbox –

0

Si elles sont toutes abstraites, je trouve qu'il est plus logique de mettre DiscriminatorMap seulement dans l'entité de premier niveau.