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 :

Définir une relation sans requête supplémentaire ?


Sujet :

Doctrine2 PHP

  1. #1
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut Définir une relation sans requête supplémentaire ?
    Bonjour,

    Je dispose de deux entités reliées par une relation unidirectionnelle de type ManyToOne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class A
    {
        /**
         * @ManyToOne(targetEntity="B")
         */
        protected $b;
    }
     
    class B
    {
    }
    A la création d'un nouvel objet A, je reçois d'un formulaire l'identifiant de l'entité B reliée. Ainsi, j'aimerais pouvoir faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $a = new A();
    $a->setB($clePrimaireDeB);
    $em->persist($a);
    $em->flush(),
    ou setB est définie ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public function setB($b)
    {
        $this->b = $b;
    }
    Toutefois, cela ne fonctionne pas, j'obtiens une erreur me disant que l'entité B est inconnue et qu'il faut que je la persiste avant. J'ai donc deux solutions : ou alors je créé une entité B from scratch et je fais un persist, ou alors je suis obligé de modifier ma fonction setB de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public function setB($b)
    {
        if (is_numeric($b)) // $b est un identifiant
           $b = $em->find('B', $b);
     
        $this->b = $b;
    }
    D'une part cela alourdit le code et, d'autre part, c'est une requête pour rien étant donné que je suis SÛR qu'il existe un enreigstrment dans la table avec l'identifiant que je récupère de mon formulaire.

    Y a t-il donc un moyen de définir une relation directement avec l'identifiant de l'objet plutôt que l'objet lui même ?

    Merci

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 146
    Points : 262
    Points
    262
    Par défaut
    Pourquoi tu n'utilise pas directement ton entité dans ton formulaire ?

    Ça te renverra directement l'entité utilisable.

  3. #3
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Citation Envoyé par Tolriq Voir le message
    Pourquoi tu n'utilise pas directement ton entité dans ton formulaire ?

    Ça te renverra directement l'entité utilisable.
    Je comprends pas. Je récupère l'identifiant à partir d'un <select>, je ne peux pas y stocker mon entité ??

  4. #4
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Salut,

    je suis novice, mais il me semble que ton cas correspond à l'exemple en 9.2 de la doc. http://www.doctrine-project.org/docs...ociations.html (je n'ai pas transposé):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    $user = $em->find('User', $userId);
     
    // unidirectional many to one
    $myFirstComment = new Comment();
    $user->setFirstComment($myFirstComment);
     
    $em->persist($myFirstComment);
    $em->flush();
    Merci de me dire si je dis une bétise!

  5. #5
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Citation Envoyé par philip40 Voir le message
    Salut,

    je suis novice, mais il me semble que ton cas correspond à l'exemple en 9.2 de la doc. http://www.doctrine-project.org/docs...ociations.html (je n'ai pas transposé):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    $user = $em->find('User', $userId);
     
    // unidirectional many to one
    $myFirstComment = new Comment();
    $user->setFirstComment($myFirstComment);
     
    $em->persist($myFirstComment);
    $em->flush();
    Merci de me dire si je dis une bétise!
    Non, ça n'a pas de rapport avec mon soucis .

    Mais merci quand même .

  6. #6
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2004
    Messages : 318
    Points : 362
    Points
    362
    Par défaut
    Je pense que tu n'ais pas vraiment le choix, en fait. Comme Doctrine est fait, tu ne peux pas faire un '$a->setB($clePrimairedeB)', à moins effectivement de modifier le setter directement, mais ca obligerait d'y embarquer un EntityManager.

    Ton objet B existe bien quand tu veux créer ton A, vu que tu as ta clé primaire. Quand tu dis "créer" l'entité from scratch, je ne vois pas trop, ca prend juste une seule ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $b = $em->getRepository('Bundle:EntiteB')->find($clePrimairedeB);
    $a->setB($b);
    A moins que je n'ai pas du tout compris ton problème en fait...

  7. #7
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Citation Envoyé par Guybrush113 Voir le message
    Je pense que tu n'ais pas vraiment le choix, en fait. Comme Doctrine est fait, tu ne peux pas faire un '$a->setB($clePrimairedeB)', à moins effectivement de modifier le setter directement, mais ca obligerait d'y embarquer un EntityManager.

    Ton objet B existe bien quand tu veux créer ton A, vu que tu as ta clé primaire. Quand tu dis "créer" l'entité from scratch, je ne vois pas trop, ca prend juste une seule ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $b = $em->getRepository('Bundle:EntiteB')->find($clePrimairedeB);
    $a->setB($b);
    A moins que je n'ai pas du tout compris ton problème en fait...
    Oui voilà c'est exactement ça. Le problème ? C'est pas vraiment un soucis en soi (après tout, c'est pas une ligne et une requête minime qui vont me tuer), mais je voulais juste savoir si c'était possible, puisque finalement je suis obligé de faire une requête supplémentaire qui n'aurait pas été obligatoire avec du SQL natif.

  8. #8
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2004
    Messages : 318
    Points : 362
    Points
    362
    Par défaut
    D'accord je vois plus ta question.
    On fonctionne très rarement avec les clés primaires avec Doctrine, surtout avec les instances d'entité. Mais effectivement pour les formulaires et les paramètres POST, passer des ID c'est plus simple niveau code.

    Mais je ne pense pas que ca empiète beaucoup la performance de faire un find($id).

  9. #9
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Je me permet de remonter ce sujet qui pourra surement aider d'autres personnes. IL Y A UNE SOLUTION . Trouvée sur IRC.

    Il faut utiliser la méthode getReference de l'entity manager qui permet de récupérer un proxy de l'objet via l'ID :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public function setB($b)
    {
        if (is_numeric($b)) // $b est un identifiant
           $b = $em->getReference('B', $b);
     
        $this->b = $b;
    }

  10. #10
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2004
    Messages : 318
    Points : 362
    Points
    362
    Par défaut
    Je pense que ce getReference va chercher dans les entités en mémoire dans l'entity manager (entités ou relations).
    Il ne faut pas confondre avec un find, qui lui va charger une nouvelle entité. Non ?

    Je réfléchit à voix haute, mais ca serait bien de connaitre leurs différences

  11. #11
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Citation Envoyé par Guybrush113 Voir le message
    Je pense que ce getReference va chercher dans les entités en mémoire dans l'entity manager (entités ou relations).
    Il ne faut pas confondre avec un find, qui lui va charger une nouvelle entité. Non ?

    Je réfléchit à voix haute, mais ca serait bien de connaitre leurs différences

    J'avais demandé sur le chan IRC de Doctrine. getReference se contente de créer un proxy de l'entité et d'y placer l'identifiant que tu lui as donné. Il ne récupère rien en mémoire, ne fait aucune requête SQL.

    Bref, c'est exactement ce que je cherchais : m'éviter de faire un find pour récupérer un objet dont je connais déjà l'ID juste pour établir une relation.

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

Discussions similaires

  1. Définir une relation 1-1
    Par Proxy dans le forum Hibernate
    Réponses: 4
    Dernier message: 07/02/2012, 13h05
  2. Réponses: 8
    Dernier message: 22/10/2011, 12h41
  3. Définir une zone sans tableau
    Par Invité dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 24/06/2009, 15h17
  4. Une relation , des requêtes
    Par Yanou-78 dans le forum Langage SQL
    Réponses: 12
    Dernier message: 12/02/2008, 11h55
  5. Comment définir une relation d'équivalence ?
    Par Amon-Râ dans le forum Prolog
    Réponses: 10
    Dernier message: 19/09/2006, 00h27

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