[Doctrine] Jointure sur entité fille via entité mère

a marqué ce sujet comme résolu.

Bonjour à tous,

Je cherche à réduire le nombre de requête sur une page et malheureusement je suis arrivé sur une impasse et je n’ai pas vraiment de bonne idée pour la contourner

Voici la situation :

Une requête récupère toutes les entités que je vais appeler dans le cadre de l’exemple Contenant qui possède une relation OneToOne avec une entité abstraite ContenuMere. Cette entité possède plusieurs type d’entité fille ContenuFille1 et ContenuFille2. Chaque fille possède différentes relation avec d’autres entités. Appelons les Info1, Info2,etc. L’héritage entre ContenuMere et ContenuFille est une jointure comme spécifiée ici : https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/inheritance-mapping.html#class-table-inheritance

Voici un schéma simple :

Schéma
Schéma

Ce que j’aimerais faire c’est récupérer tous les Contenants et récupérer toutes les entités jusqu’au Infos associées à travers l’entité ContenuMere sans, si possible, faire une requête monstrueuse et immaintenable qui hydrate ensuite mes objets PHP

Le soucis ici c’est que les jointures vers Infos n’existent pas sur ContenuMere donc Doctrine ne peut pas suivre les jointures. J’ai essayé d’expliciter la jointure ContenuMere-ContenuFille mais malheureusement ça empêche l’hydratation d’entité car je me retrouve avec un tableau me retournant ContenuMere et ContenuFille côte à côte

Après avoir cherché plusieurs heures je ne vois pas trop quoi faire à part abandonner l’idée d’optimiser cette page. Si vous avez des idées ou des pistes je suis partant

Merci d’avance pour votre aide

+0 -0

Salut !

Ça me paraît bien pointu comme demande, et je ne suis pas sûr d’avoir bien saisi si c’est une solution à ton problème, mais il semble que tu puisses redéfinir en partie les relations avec Doctrine, cf. cette partie de la documentation. L’exemple fait mention de traits, peut-être que ça peut dans une certaine mesure être adapté à des héritages "plus classiques", sinon ta structure pourrait être adaptée pour utiliser un ou plusieurs traits ?

+0 -0

@Ymox, en fait j’ai pas besoin de surcharger des champs de la table mère mais de pre-load les contenus des relations filles pour éviter d’avoir 300–400 requêtes par page ensuite

Voici le code php associé si j’essaie de récupérer simplement les Contenant avec les ContenuMere

//Dans un repository
$this->createQueryBuilder("c")
    ->innerjoin("c.contenuMere", "cm")
    ->addSelect("cm");

Maintenant voici les deux méthodes que j’ai essayé pour récupérer les Infos avec (qui ont une relation N..N avec ContenuFille1 et ContenuFille2

//Dans un repository
$this->createQueryBuilder("c")
    ->innerjoin("c.contenuMere", "cm")
    ->addSelect("cm")
    ->leftJoin("cm.infos1", "i1")
    ->addSelect("i1");

Cette méthode ne fonctionne bien sûr pas, étant donné que infos1 n’existe pas dans ContenuMere mais seulement dans ContenuFille

//Dans un repository
$this->createQueryBuilder("c")
    ->innerjoin("c.contenuMere", "cm")
    ->addSelect("cm")
    ->leftJoin(Infos1::class, "i1", "WITH", "cm MEMBER OF i1.contenus")
    ->addSelect("i1");

Ici le soucis que j’ai c’est qu’au lieu de me retrouver avec un objet Contenant correctement hydraté et les collections bien chargées, je me retrouve avec un tableau alternant des Contenant et des Info1 (cette méthode est l’équivalent de "connect by prior … start with …" qui est pour Oracle. On utilise WITH et JOIN avec SQL et Doctrine)

J’espère avoir clarifié le problème que j’ai ^^

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte