2010-10-14 11 views
5

Używam Doctrine2 zarządzać mojego modelu poniżej: Jest pojęciem abstrakcyjnym Content z Composite wzór w Gallery, także pojęcie abstrakcyjne Media z którego Video i Image dziedziczy.Wiele poziomów dyskryminacji podczas korzystania Doctrine2

Mój wybór był dodać dyskryminatory do Content i Media tabel w celu dokonania rozróżnienia między Gallery, Video i Image. Content używa JOIN inheritance i Media używa SINGLE_TABLE inheritance.

Po uruchomieniu doctrine orm:schema-tool:create --dump-sql, Media tabela powtarza kolumny z Content. To wyjście polecenia:

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 

Oto moje zajęcia i adnotacje:

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 
{ 
} 

pytam: To jest poprawne zachowanie? Czy nie powinno być Media mieć tylko pola id, width i height, plus bitrate i z Video?

Poza tym, czy istnieje sposób na pozbycie się niepotrzebnego stołu Gallery?

Mam nadzieję, że jasno to wyjaśniłem. Z góry dziękuję.

AKTUALIZACJA: Nie ma mowy. Próbowałem znaleźć jeszcze prostszy przykład, który nie pokazuje tego zachowania, ale nie znalazłem żadnego.

Wszelkie sugestie? Czy to może być błąd w Doctrine 2 lub brakuje mi prostszego rozwiązania?

Odpowiedz

5

Odpowiadam na moje pytanie, mając nadzieję, że kiedyś komuś pomoże.

Z tym pytaniem otworzyłem bug report in github for doctrine2 i odpowiedź jest całkiem jasna: nie jest to obsługiwane.

AKTUALIZACJA 2013/07/27

Właśnie próbowałem z doktryną 2.3.4 i działa zgodnie z oczekiwaniami.: D

+0

Jestem też z doktryną 2.3.4, ale zachowanie nie działa. Tabela Media nie jest utworzona, czy masz jakieś uwagi? –

+0

Możesz zobaczyć mój test tutaj: https://github.com/paulandrieux/MultipleInheritanceSandbox –

0

Jeśli wszystkie są abstrakcyjne, to bardziej sensowne jest umieszczanie DiscriminatorMap tylko w jednostce najwyższego poziomu.

Powiązane problemy