IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Doctrine2 PHP Discussion :

Gestion de l'heritage avec Symfony2/Doctrine2


Sujet :

Doctrine2 PHP

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2015
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Gestion de l'heritage avec Symfony2/Doctrine2
    Bonjour à toutes et à tous,
    J'ai vraiment cherché partout avant de poster, mais étrangement je n'ai pas trouvé de réponse, pourtant il me semble que mon souci est ultra classique...

    Je veux gérer un ensemble de programmes qui peuvent avoir des propriétés différentes en fonction de leur type, mais étant donné qu'un tas de relation s'appliquent à l'ensemble des programmes, il me parait naturel dans mon modèle d'utiliser l’héritage pour ne pas avoir à multiplier les relations et bien sur optimiser l'espace utilisé par la base.

    Voici un extrait du modèle (simplifié) :

    Nom : modele_simplifié.JPG
Affichages : 4784
Taille : 48,3 Ko

    J'ai créé mon modèle dans Doctrine et j'ai du coup (entres autres) :

    class Programme
    {
    ...
    }

    class Film Extends Programme
    {
    ...
    }

    class Spectacle Extends Programme
    {
    ...
    }

    Dans mes entités filles, je n'ai mis aucune annotation concernant l'héritage, quand j’exécute la commande doctrine:schema:update, il me créé bien les tables Programme, Film et Spectacle, mais ce qu'il fait c'est créer les tables filles avec toutes les propriétés de la classe mère. Du coup déjà, je perds l'interet de l'héritage au niveau du stockage des données et d'autre part la table programme n'est finalement jamais remplie.

    Mais encore pire que tout, lorsque je veux renseigner les pays rattachés à un programme (j'utilise la fonctionnalité des fixtures), via une table programme_pays (créée par doctrine car c'est une relation ManyToMany), j'ai une erreur de violation de clé étrangère, un peu comme si il cherchait à inserer des données en doublons dans la table programme_pays, une fois pour le programme et une fois pour le film, ce qui semble deja assez improbable vu que les id devraient être differents...

    Bref, je suis un peu perdu sur la gestion de l'héritage par Doctrine...Je ne suis pas sur d'être très clair, n'hésitez pas à me poser des questions si le coeur vous en dit de m'aider... !

    Merci d'avance et à bientot !

    PS: je peux très bien contourner le problème de l'héritage en ajoutant une entité TYPE-PROGRAMME(Id, libelle) qui contiendrait Film et spectacle), mais il me semble que ce serait plus propre, conceptuellement parlant, de faire un héritage...

  2. #2
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 296
    Points
    7 296
    Par défaut
    Bonjour,

    L'héritage n'existe pas en SQL en tant que tel.

    Tu peux le faire de 2 manières, que tu devras choisir dans doctrine.

    Soit tu a une table qui contient toutes les données et une colonne type. C'est pas trop mal si tu as peu de variations entre les deux classes filles.
    Soit tu as une classe mère avec les infos communes et une relation 1 - 0..1 avec 2 ou plus classe filles.

    A toi de choisir et de voir ce que tu préfère coté SQL pour tes perf.
    http://doctrine-orm.readthedocs.org/...e-mapping.html

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2015
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Merci pour ta réponse. Ca me conforte dans mon idée. Je sais que le SQL ne gère pas l'héritage, je débute dans Symfony mais pas dans le SQL, je pensais que ça aurait pu être géré par Symfony (j'ai peut être pas posté au bon endroit du coup ?), par la gestion des classes et les méthodes.

    Je pense donc que je vais faire ce que j'avais pensé initialement, toutes les tables filles contiendront l'id de la table mère créée au même moment et le constructeur de la classe fille créera en parallèle l'objet mère, c'est pas plus compliqué finalement, c'est dommage que ce ne soit pas géré par le framework...

    La c'était un modèle simplifié mais en gros j'ai au moins 5 relations et minimum 4 entités filles. Si je supprime la notion d'héritage ça me fait 20 relations au lieu de 5 !

  4. #4
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 296
    Points
    7 296
    Par défaut
    c'est géré : http://doctrine-orm.readthedocs.org/...le-inheritance

    Enfin, je pense que c'est ce que tu veux faire.

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2015
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Citation Envoyé par pmithrandir Voir le message
    c'est géré : http://doctrine-orm.readthedocs.org/...le-inheritance

    Enfin, je pense que c'est ce que tu veux faire.
    Non, ça ne fait pas ce que je veux. Concrètement Doctrine duplique les propriétés de la mère dans le stables filles et Symfony n'en fait rien du tout. Rien n'est généré dans les classes pour faire interagir les 2 objets.

  6. #6
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 296
    Points
    7 296
    Par défaut
    Regarde bien la doc.
    Tu as 2 cas :
    * @InheritanceType("SINGLE_TABLE")
    * @InheritanceType("JOINED")

    Le single table fait ce que tu dis, mais le joined réparti les données sur n+1 table avec n le nombre de parents et des clefs étrangères pour faire le lien.

  7. #7
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2015
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Mais oui ! Ca marche parfaitement ! C'est exactement ce que je voulais faire, c'est juste que j'en avais pas bien compris le principe !!! Merci 1000 fois !

    Alors pour ceux comme moi qui n'avaient pas compris la doc en anglais que je trouve vraiment mal expliquée, voici un cas concret (le mien) qui permettra de piger je pense (j'espère) :

    J'ai une entité Programme qui contient un certains nombre de propriétés partagées par toutes filles : Film, Serie, Spectacle

    Voici les déclarations :

    Entity/Programme.php :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /**
     * @ORM\Table("programme")
     * @ORM\Entity(repositoryClass="LldvdBundle\Entity\ProgrammeRepository")
     * @ORM\InheritanceType("JOINED")
     * @ORM\DiscriminatorColumn(name="discr", type="string")
     * @ORM\DiscriminatorMap({"programme" = "Programme", "film" = "Film", "serie"="Serie","spectacle"="Spectacle"})
    */
    class Programme
    {
       private $id;
       private $titreOriginal;
       private $titreFrancais;
       private $duree;
     
       /**
         * @ORM\ManyToMany(targetEntity="LldvdBundle\Entity\Pays", cascade={"persist","remove"}, inversedBy="programmes")
         * @ORM\JoinTable(name="programmes_paysListe")
         * @ORM\JoinColumn(nullable=false)
         */
        private $paysListe;
    }
    Ce que je n'avais pas pigé : la clause Discriminator de Doctrine rajoute un champs "discr" (qu'on peut évidemment appeler comme on veut) de type string qui contiendra le type du programme "film" si c'est un Film, "spectacle" si c'est un spectacle, etc... Il créera automatiquement un objet de type Programme, puis l'identifiant unique servira pour la clé étrangère dans les tables filles film, spectacle et serie.

    Les entités filles :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Film extends Programme
    {
    private $dateSortieCinema;
    ...
    }
     
    class Serie extends Programme
    {
    ...
    }
     
    class Spectacle extends Programme
    {
    private $datePremiereRepresentation
    ...
    }

    L'entité Pays (pour montrer l'exemple de la relation many to many rattachée à la table mère et qui suit bien l'héritrage) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Pays {
     
         private id;
         private libellePays;
     
        /**
         * @var string
         *
         * @ORM\ManyToMany(targetEntity="Programme", mappedBy="listePays")
         */
        private $programmes;
     
    ...
    }
    Ce que je n'avais pas pigé : doctrine rajoute un champs "discr" de type string qui contiendra le type du programme "film" si c'est un Film, "spectacle" Si c'ets un spectacle, etc... Il creera automatiquement un objet de type Programme, puis l'identifiant unique servira pour la clé étrangère dans le stables filles film, spectacle et serie

    Du coup dans mes fixtures, pour créer un film je n'ai plus qu'à faire ça :

    $film1 = new Film();

    $film1->setDateSortieCinema(new \Datetime('1985-10-23'));
    $film1->setTitreFrabcais("Retour vers le futur");
    $film1->setTitreOriginal("Back to the future");
    $film1->setDuree(105);
    $film1->addPays($this->getReference('usa'));
    $manager->persist($film1);
    $manager->flush();

    Et ça fait tout ce qu'il faut en base ! Et le tout, sans dupliquer les propriétés de la table mere dans le stables filles. Bref, c'est impeccable !

    J'espère que ce poste servira à d'autres !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [2.x] Créer une application avec Symfony2 et Doctrine2
    Par webornot dans le forum Symfony
    Réponses: 3
    Dernier message: 29/05/2011, 23h10
  2. Réponses: 4
    Dernier message: 30/12/2004, 18h04
  3. Réponses: 3
    Dernier message: 13/08/2004, 18h52
  4. [TP]Gestion des images bmp avec BMP.TPU
    Par Gabi dans le forum Turbo Pascal
    Réponses: 9
    Dernier message: 14/05/2004, 23h20
  5. [CVS]Gestion de 2 versions avec une partie commune
    Par Gromitou dans le forum EDI et Outils pour Java
    Réponses: 4
    Dernier message: 19/02/2004, 14h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo