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 :

Favoriser ou éviter les relations Bidirectionnelles?


Sujet :

Doctrine2 PHP

  1. #1
    Membre à l'essai
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2011
    Messages : 26
    Points : 13
    Points
    13
    Par défaut Favoriser ou éviter les relations Bidirectionnelles?
    Bonjour,

    Pouvez-vous me donner la réponse à la question se trouvant en titre ?

    D'avance merci.

  2. #2
    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
    Les relations Doctrine ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2011
    Messages : 26
    Points : 13
    Points
    13
    Par défaut
    Oui, dans les relations doctrines.

    Est-il préférable de toujours utiliser des relations bidirectionnelles ou alors créer des requêtes dans le repository ?

    Un exemple : une entité Livre et une entité Catégorie.
    L'entité Livre appartient à une catégorie.
    Dans le cas où l'on voudrait afficher tous les livres d'une catégorie, devrait-on favoriser la relation bidirectionnelle ou une requête?

  4. #4
    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
    J'ai un peu de mal à vraiment comprendre ta question

    A mon avis il est toujours mieux de d'exploiter au maximum les possibilités de Doctrine. Si tu as une requête spécifique (on en a souvent), la création d'un Repository personnalisé est une bonne façon de faire.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2011
    Messages : 26
    Points : 13
    Points
    13
    Par défaut
    Merci pour ta réponse.

    Je vais essayer d'être un peu plus précis car j'avoue que mes idées sont un peu confuses (je débute avec ce framework).

    Je reprends mon exemple de Livre et Catégorie.

    Si je ne me trompe quand je crée la relation bidirectionnelle avec Doctrine,
    une instance de mon entité Catégorie possède à chaque fois, la liste des livres qui lui sont "attachés". D'une certaine façon, on accède donc vite à cette liste de livre.

    Mais lorsque l'on veut que la liste des catégories, si la liste des livres se crée aussi, j'ai l'impression que cela provoque une perte de performance et donc, dans ce cas, créer une relation unidirectionnelle et une requête spécifique dans le repository pour obtenir les livres de la catégoire est peut-être plus intéressante.

    Est-ce que je me trompe ?
    Dans le cas où non, la différence de performance, fait pencher la balance sur quelle méthode (relation bidirectionnelle ou repository) ?

    Merci d'avance.

  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
    Ah, je crois avoir compris

    Il me semble pas que cela se passe comme tu décris, sinon Doctrine perdrait un de ses intérêt.
    Je pense que Doctrine exécute la requête vers la base de données uniquement quand tu fais un $categorie->getLivres().

    En espérant t'avoir aidé !

  7. #7
    Membre averti
    Inscrit en
    Août 2007
    Messages
    360
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 360
    Points : 396
    Points
    396
    Par défaut
    Bonjour,

    N'étant qu'un spécialiste doctrine2, je pense toute de même que Guybrush113 serait dans le vrai...

    Par ailleurs, j'ai trouvé un article parlant de ces techniques :

    http://www.doctrine-project.org/docs...h-associations

    En espérant avoir contribué un peu,

    Cordialement,

    Mathieu

  8. #8
    Membre à l'essai
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2011
    Messages : 26
    Points : 13
    Points
    13
    Par défaut
    Ben dans ce cas, je vais favoriser les relations bidirectionnelles.

    Un grand merci à vous 2.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 21
    Points
    21
    Par défaut
    Je ne suis pas d'accord avec Guybrush113, si tu as des associations dans tes entities alors elles seront chargé à chaque fois.

    Il est très simple de vérifier cela.
    Tu n'as qu'à faire un find() sur ton entitie "categorie" et de faire un var_dump de ton objet, tu verras que tu auras tout les objets livres dans ton dump.

    C'est pour cela que je privilégie les associations unidirectionnelles.
    Dans tous les cas, un bon système de cache pour stocké les résultats est nécessaire dans n'importe quel type d'application web.

  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
    Oui effectivement, vu d'un var_dump on voit tout les liens.

    Et du coup, une association unidirectionnelle ca fonctionnerait comment ? Pour notre exemple de ce topic :p

  11. #11
    Membre du Club
    Homme Profil pro
    developpeur
    Inscrit en
    Février 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Février 2010
    Messages : 54
    Points : 65
    Points
    65
    Par défaut
    Bonjour,
    dans la mesure où tu n'écris pas explicitement ta jointure en DQL, Doctrine favorise un chargement "paresseux". C'est à dire qu'il n'effectue qu'une requête sur la table demandée même si celle ci contient des relations avec d'autres tables.

    Tu as sûrement remarqué que suite à une requête simple vers Categorie il ne te renvoie pas un objet Categorie mais CategorieProxy. Cet objet ressemble fortement à Categorie sauf pour la méthode getLivres(). Dans cette méthode, CategorieProxy effectue d'abord une requête pour récupérer les livres et seulement après te renvoie tes objets livres. Tant que tu n'as pas appelé la méthode getLivres() aucune requête sur la table Livre n'est effectuée.

    Voici une explication sur le site doctrine
    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
     
    <?php
    class CategorieProxy extends Categorie implements Proxy
    {
        private function _load()
        {
            // lazy loading code
        }
     
        public function getLivres()
        {
            $this->_load();
            return parent::getLivres();
        }
        // .. other public methods of User
    }
    Ainsi, seuls tes objets demandés sont chargés en mémoire. Tu peux donc utiliser des relations bidirectionnelles sans avoir ce soucis.
    Explication plus précise dans la doc Doctrine : proxy classes

    Encore

  12. #12
    Membre du Club
    Homme Profil pro
    developpeur
    Inscrit en
    Février 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Février 2010
    Messages : 54
    Points : 65
    Points
    65
    Par défaut
    Je ne retrouve plus le passage où Doctrine propose une alternative à var_dump afin d'avoir une vraie vision des objets chargés.

  13. #13
    Membre du Club
    Homme Profil pro
    developpeur
    Inscrit en
    Février 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Février 2010
    Messages : 54
    Points : 65
    Points
    65
    Par défaut
    ici :
    Lazy load proxies always contain an instance of Doctrine’s EntityManager and all its dependencies. Therefore a var_dump() will possibly dump a very large recursive structure which is impossible to render and read. You have to use Doctrine\Common\Util\Debug::dump() to restrict the dumping to a human readable level. Additionally you should be aware that dumping the EntityManager to a Browser may take several minutes, and the Debug::dump() method just ignores any occurrences of it in Proxy instances.

    http://www.doctrine-project.org/docs...irst-prototype

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 21
    Points
    21
    Par défaut
    Merci pour tes explications lhapaipai mais quand je test un objet avec Doctrine\Common\Util\Debug::dump(); suite à un simple find j'ai bien mes 2 objet chargés.

    Exemple :

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
     
    /**
     * Core_Models_User
     * @Table(name="core_user")
     * @Entity
     */
    class Core_Models_User
    {
        /**
         * @var integer $user_id
         *
         * @ORM\Column(name="user_id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="IDENTITY")
         */
        public $user_id;
     
        /**
         * @var int $role_id
         *
         * @ORM\Column(name="role_id", type="integer")
         */
        public $role_id;    
     
        /**
         * @var string $user_name
         *
         * @ORM\Column(name="user_name", type="string", length=100)
         */
        public $user_name;
     
        /**
         * @var string $password
         *
         * @ORM\Column(name="password", type="string", length=50)
         */
        public $password;
     
        /**
         * @OneToOne(targetEntity="Core_Models_Role", mappedBy="user")
         * @JoinColumn(referencedColumnName="role_id")
         */    
        private $role;  
     
         /**
         * Get Role 
         *
         * @return Core_Models_Role 
         */
        public function getRole()
        {
            return $this->role;
        }   
     
         /**
         * Set Role 
         *
         * @param Core_Models_Role $oRole
         * @return void
         */
        public function setRole(Core_Models_Role $oRole) {
        	$this->role = $oRole;
        }
     
    ......
     
    }
    Donc j'ai associé mon model Core_Models_User avec une association OnetoOne sur mon Core_Models_Role.

    Voici le résultat de mon dump :

    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
     
    object(stdClass)[867]
      public '__CLASS__' => string 'Core_Models_User' (length=16)
      public 'user_id' => int 2
      public 'role_id' => string '2' (length=1)
      public 'user_name' => string 'jonathan' (length=8)
      public 'password' => string '1ee2b5b006e9e5f03df7bbc39820ac8c' (length=32)
      public 'full_name' => string '' (length=0)
      public 'firstname' => string 'jojojo' (length=6)
      public 'lastname' => string 'frzer' (length=5)
      public 'company' => string '4964694' (length=7)
      public 'civility' => string 'm' (length=1)
      public 'phone' => string '1313113' (length=7)
      public 'mobile' => string '131321313' (length=9)
      public 'fax' => string '131312' (length=6)
      public 'email' => string 'xxxx@xxxx.fr' (length=19)
      public 'is_active' => int 1
      public 'role' => 
        object(stdClass)[1015]
          public '__CLASS__' => string 'Core_Models_Role' (length=16)
          public 'role_id' => int 2
          public 'name' => string 'customer' (length=8)
          public 'description' => string 'customer' (length=8)
          public 'locked' => int 1
      public 'lang' => string 'fr_FR' (length=5)
    Donc je constate que les 2 objets sont chargés juste avec un find().

  15. #15
    Membre à l'essai
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2011
    Messages : 26
    Points : 13
    Points
    13
    Par défaut
    Merci lhapaipai pour tes liens.

    Je vais lire tout cela.

    En tout cas, je vois que ma question suscite de grandes réflexions

  16. #16
    Membre du Club
    Homme Profil pro
    developpeur
    Inscrit en
    Février 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Février 2010
    Messages : 54
    Points : 65
    Points
    65
    Par défaut
    oups

    Je rencontre la même situation que toi.

    Cependant, en utilisant un débuggeur tu peux voir que la propriété role s'est remplie d'objets Core_Models_Role suite à l'exécution de la méthode dump de Doctrine et non suite au find.

    Je suppose donc que la fonction dump de Doctrine sert à simplifier l'objet retourné par find afin qu'il se présente comme ton entité mais qu'il parcoure quand même ton arborescence.

    Bonne journée

  17. #17
    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
    Merci lhapaipai

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 17
    Points : 21
    Points
    21
    Par défaut
    exact raah foutu dump.

    En appellant la méthode Doctrine\DBAL\Logging\EchoSQLLogger qui permet de voir les requetes exécuter, j'ai vu effectivement qu'aucune jointure n'est réalisé suite à mon find.

    merci lhapaipai je vais donc pouvoir me "lâcher" sur les associations .

    Il faudrait vraiment un site dédié à doctrine2 pour les francophones car la doc un peu flou parfois je trouve.

  19. #19
    Membre à l'essai
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2011
    Messages : 26
    Points : 13
    Points
    13
    Par défaut
    Désolé,
    j'essaie de suivre la discussion mais je suis sur plusieurs projets en même temps.
    En tout cas, un grand merci pour vos détails.

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

Discussions similaires

  1. Relation bidirectionnelle à favoriser ?
    Par Grumium dans le forum Hibernate
    Réponses: 6
    Dernier message: 18/01/2010, 15h01
  2. Hibernate et les relations pere/enfant
    Par kurkLord dans le forum Hibernate
    Réponses: 6
    Dernier message: 19/01/2005, 05h37
  3. Comment éviter les doublons dans ma table
    Par einegel dans le forum Bases de données
    Réponses: 3
    Dernier message: 09/11/2004, 13h18
  4. Éviter les doublons dans une requete
    Par royrremi dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 03/08/2004, 20h37
  5. [Relations] afficher les relations entre 2 tables
    Par dzincou dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 14/01/2004, 18h07

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