Bonjour,
Pouvez-vous me donner la réponse à la question se trouvant en titre ?
D'avance merci.
Bonjour,
Pouvez-vous me donner la réponse à la question se trouvant en titre ?
D'avance merci.
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?
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.
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.
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é !
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
Ben dans ce cas, je vais favoriser les relations bidirectionnelles.
Un grand merci à vous 2.
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.
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
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
Ainsi, seuls tes objets demandés sont chargés en mémoire. Tu peux donc utiliser des relations bidirectionnelles sans avoir ce soucis.
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 }
Explication plus précise dans la doc Doctrine : proxy classes
Encore
Je ne retrouve plus le passage où Doctrine propose une alternative à var_dump afin d'avoir une vraie vision des objets chargés.
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
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 :
Donc j'ai associé mon model Core_Models_User avec une association OnetoOne sur mon Core_Models_Role.
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; } ...... }
Voici le résultat de mon dump :
Donc je constate que les 2 objets sont chargés juste avec un find().
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)
Merci lhapaipai pour tes liens.
Je vais lire tout cela.
En tout cas, je vois que ma question suscite de grandes réflexions
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
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.
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.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager