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 :

[Relation]Problème mapping OneToMany


Sujet :

Doctrine2 PHP

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 102
    Par défaut [Relation]Problème mapping OneToMany
    Bonjour tout le monde,

    Je suis en train d'essayer de migrer un projet en utilisant Doctrine2, mais j'ai quelques problèmes pour la gestion des relations OneToMany et ManyToOne.
    Le problème, c'est que j'ai une base de la sorte :
    Table : episodes_series
    id
    sid #Serie ID
    num #Numéro de l'épisode

    Table : episodes_titre
    eid #Episode id
    lang
    titre
    Mais mon problème, c'est que pour mon entité Episode quel types de relation dois-je utiliser, car je n'arrive pas à trop comprendre car je penses utiliser la relation OneToMany mais ne je suis pas sur que ça soit celle qui soit la plus adapter à mon cas (plusieurs titres possible pour un même épisode).

    Car pour le moment j'était parti sur une relation OneToMany (1-N) mais je penses avoir fait des erreurs au niveau des paramètres. En effet, que dois-je mettre dans le champs mappedBy car je ne vois pas trop, là j'ai mis id mais je penses pas que ça soit la bonne solution.

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    /**
     * @ORM\Entity
     * @ORM\Table(name="public.episodes_series")
     */
    class Episode
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
        /**
         * @ORM\Column(type="integer")
         */
        protected $num;
     
        /**
         * @ORM\OneToMany(targetEntity="EpisodeTitle",mappedBy="eid")
         * @ORM\JoinTable(name="episodes_titles",
         *  joinColumns={@ORM\JoinColumn(name="eid", referencedColumnName="id")},
         *  inverseJoinColumns={@ORM\JoinColumn(name="id", referencedColumnName="eid")})
         */
        protected $titre;
    } 
     
    /**
     * @ORM\Entity
     * @ORM\Table(name="public.episodes_titre")
     */
    class EpisodeTitle
    {
         /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
         /**
         * @ORM\Column(type="string")
          */
        protected $titre;
    En effet, Doctrine génère les requêtes suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT t0.id AS id1, t0.num AS num2 FROM public.episodes_series t0 WHERE t0.id = ?
    SELECT t0.id AS id1, t0.titre AS titre2, t0.lang AS lang3, t0.eid_id AS eid_id4 FROM public.episodes_titre t0 WHERE t0.eid_id = ?
    Hors mon problème c'est d'où sort ce champs eid_id, pourquoi rajoute-t-il _id ?

    Merci par avance et bonne soirée

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 319
    Par défaut
    Salut,

    Tu t'es un peu emmelé les pinceaux en effet. Je te propose de lire le chapitre que j'ai écrit la dessus et qui sera une bonne base pour que tu comprennes !

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 102
    Par défaut
    Merci beaucoup pour la réponse rapide, donc si j'ai tout compris j'ai pris le problème à l'envers et c'est ça qu'il faudrait faire :
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    /**
     * @ORM\Entity
     * @ORM\Table(name="public.episodes_series")
     */
    class Episode
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
        /**
         * @ORM\Column(type="integer")
         */
        protected $num;
     
        public function addTitre(\Serie\EpisodeBundle\Entity\EpisodeTitle $titre){
            $this->setEid($this);
        }
    } 
     
    /**
     * @ORM\Entity
     * @ORM\Table(name="public.episodes_titre")
     */
    class EpisodeTitle
    {
         /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
         /**
         * @ORM\Column(type="string")
          */
        protected $titre;
     
        /**
         * @ORM\ManyToOne(targetEntity="Episode")
         * @ORM\JoinColumn(name="eid", referencedColumnName="id")
         */
        protected $eid;
    Jusque là je pense avoir bon. Donc après, pour récupérer un épisode, j'ai trouvé ça comme solution :
    • Utiliser un EntityRepository (mais là je vois pas trop comment faire avec les jointures)
    • Faire un appel du genre : $this->getDoctrine()->getRepository('SerieEpisodeBundle:EpisodeTitle')->findByEid(7381);


    Le problème avec la solution 1, c'est que j'ai pas l'impréssion que ça soit fait pour être utiliser dans une relation OneToMany, car dans l'exemple proposé à chaque fois c'est du ManyToMany et quand j'essaye de l'appliquer, il m'indique bien que l'entité Episode n'a pas de relation titre pour la mapper avec l'autre.

    Or cependant je trouve ça un peut tordu et donc je me demande si j'utilise bien le truc.

    Car par exemple, si je suis sur la page pour récupérer la liste des épisodes d'une série, je ferais un truc du genre (la page affichera entre autres les informations de la série) :
    EntiteEpisode->getSerie()->getMesInfos();

    Et donc je me demandais si avec les EntiteRepo je pourrais pas faire :
    EntiteSerie->getEpisodes() ......

    Car en l'occurance, pour tout les épisodes j'aurai à chaque fois la même entité Serie et donc ça me parait un peut bizarre comme solution.

    Or le problème c'est que la série n'a pas de relation direct avec les Episode.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 319
    Par défaut
    Moi j'ai pas compris toi par contre :p

    1/ T'as des Serie et des Titre, est-ce que tu peux supprimer toute référence à "episode" qui finalement n'a aucun sens ici ?

    2/ Une Serie contient plusieurs Titre ok, ta relation ManyToOne est bonne. Sauf :
    - Dans Titre tu veux faire Titre->getSerie(), alors pourquoi t'as appelé cette propriété eid ?? (parce que tu coup tu vas faire Titre->getEid() la) Met private $serie, parce que c'est une Serie. Tu dois penser objet, pas bdd, oublie les eid.
    - Dans ta définition de la relation, supprime ta JoinColumn, Doctrine gère ca très bien tout seul avec les valeurs par défaut, ca sera plus clair pour toi si ca n'apparait pas.
    - Oublie la méthode addTitre en fait dans Serie. Garde seulement setSerie dans Titre, j'ai modifié le tuto pour ca car ca embrouille pour rien.

    3/ Après j'ai plus rien compris Je crois qu'en fait tu as vraiment un truc Episode, mais je comprends pas la différence avec Titre, etc. Est-ce que tu peux rééexpliquer stp :p

    4/ Si je n'avais qu'un seul conseil : oublie ta bdd, pense objet !

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 102
    Par défaut
    Je vais résumer le truc

    Mais juste avant, pour dire que si je vire le JoinColumn ça ne marche pas, il essaye de faire une requête sur le champ eid_idqui n'existe pas

    Actuellement j'ai un partie d'un site que je voudrais bien migrer sous Symfony2 donc je fais quelques tests

    Donc pour résumer, c'est un module qui permet de données des informations sur différentes séries TV.

    Et donc, actuellement j'ai les tables suivantes :
    • 1 table pour les Series - Nom de la table series - Champs : id de la serie, titre, description, etc...
    • 1 table pour indiquer le numéro de l'épisode ainsi que la date de diffusion - Nom de la table series_episodes - Champs : id episode, clef étrangère sur series.id , num de l'épisode, date de diffusion
    • 1 table pour indiquer le titre de l'épisode dans différentes langue - Nom de la table episodes_titre - Champs : clé étrangère sur series_episodes.id ; titre de l'épisode; code lang


    Et donc j'ai la relation suivantes :
    1 serie à N titre officiel (1 pour chaque langue qui pourrait correspondre à l'objet Title)
    1 serie à N synonyme (Titre non officiel, juste une collection de string)
    1 serie à N episodes
    1 episode à N titres (qui pourrait reprendre le même format que le titre officiel en faisant un repository pour faire un getBySerie ou un getByEpisode)

  6. #6
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 102
    Par défaut
    Bon, en relisant encore une fois le book de symfony 2, j'ai pris l'exemple de la relation Categorie -> Produits qui revient à peut près au même.

    Donc j'ai ça :
    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
     
    /**
     * @ORM\Entity
     * @ORM\Table(name="public.episodes_series")
     */
    class Episode
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
        /**
         * @ORM\OneToMany(targetEntity="EpisodeTitle", mappedBy="eid")
         */
        protected $titres;
     
    }
    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
    22
    23
    24
    25
     
    /**
     * @ORM\Entity
     * @ORM\Table(name="public.episodes_titles")
     */
    class EpisodeTitle
    {
         /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
        /**
         * @ORM\ManyToOne(targetEntity="Episode", inversedBy="episodetitles")
         * @ORM\JoinColumn(name="eid", referencedColumnName="id")
         */
        protected $eid;
     
         /**
         * @ORM\Column(type="string")
         */
        protected $titre;
    ............
    Bon j'ai mis un peut de temps à comprendre comment fonctionnait le truc, mais là je penses que c'est bon, j'arrive bien à avoir ma relation 1-N, mais je ne pensais pas qu'il fallait aussi lui indiquer la relation N-1

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 319
    Par défaut
    J'insiste, tu ne devrais pas avoir de propriété avec pour nom "eid", ce n'est pas normal ! Elle doit se nommer Episode ou autre nom sémantique, mais eid brise tout concept d'ORM !

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

Discussions similaires

  1. Mapping et relation : problème à la suppression
    Par Mr. Angus dans le forum Doctrine2
    Réponses: 2
    Dernier message: 28/07/2011, 05h44
  2. Réponses: 2
    Dernier message: 03/04/2007, 09h28
  3. Réponses: 5
    Dernier message: 29/03/2007, 16h00
  4. [hibernate]Problème mapping classe association
    Par jsl1 dans le forum Hibernate
    Réponses: 6
    Dernier message: 16/06/2006, 17h27
  5. [Hibernate & Eclipse] problème mapping
    Par sonia_ppr dans le forum Hibernate
    Réponses: 4
    Dernier message: 04/05/2006, 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