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

Hibernate Java Discussion :

Charger un graphe d'objets


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 9
    Par défaut Charger un graphe d'objets
    Bonjour,
    Mon problème est le suivant:

    J'ai un modèle objet avec une vingtaine de classes, où les OneToMany sont en LAZY.
    Mais Parfois on doit envoyer au client lourd la totalité des objets liés à un point donné du graphe; j'ai codé un bean qui par introspection va appeler size() sur toutes les collections, pour forcer le chargement des OneToMany.

    Mais c'est un peu lent, et quelqu'un m'a suggérer de tout récupérer en une fois avec une grosse requête qui fait des join fetch, la doc Hibernate a l'air de dire que ca pourrait bien forcer le chargement.

    Probleme:
    -Est-il possible de coder une telle requête, et les perfs ne seront-elles pas encore pires?
    -J'ai essayé de tester avec seulement 2 entités du graphe d'objet, avec une requete:
    "select mere from Mere mere "
    + "left join fetch mere.filles fille";
    Car on veut récupérer toutes les mères meme celles qui n'ont pas de filles.

    Probleme, quand du cote client je recupere les Meres, il y en a bien le bon nombre, mais chacune d'entre elles a, en plus de ses filles "réelles" (celles qui sont en BD) des filles "fantômes" qui sont NULL!
    Plus précisément, les mères sans filles n'ont pas de fille fantôme, mais la première mère "avec fille" de la liste a une fille NULL, la seconde 2, etc..

    Bizarre non?
    Je suis sûr qu'il y a une expliocation simple, ce n'est pas par hasard qu'on a une progression arithmetique 1,2,3, etc.. filles fantomes.

  2. #2
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 9
    Par défaut
    Pour préciser le contexte je bosse sur JBoss avec des EJB3/Hibernate, et le client est une IHM Swing avec de la cartographie. C'est pour ça qu'on a besoin de charger un gros modèle d'un coup, pour que les interactions avec la couche de gestion des tracés sur carto n'aient ensuite pas constamment des temps d'attente à cause d'interactions intempestives avec le serveur J2EE. Je répond préventivement oui, dans notre cas on a besoin de charger tout ça d'un coup.

    Je commence à penser que notre problème est technologique, on se heurte au fait que pour l'instant la gestion du LAZY ne se fait que dans une session Hibernate. Et ce qu'on voudrait c'est une façon simple et performante de surcharger ce comportement dans certains cas d'utilisations bien précis, pas seulement pour le chargement d'UNE collection mais pour charger un graphe d'objets représentant un modèle.

    Finalement je me demande si la solution la plus élégante ne serait pas, en l'état actuel de la technologie de mapping O/R, d'avoir , pour chaque classe du graphe de modèle, une classe surchargeant les getters OneToMany en EAGER (dans les Entity de base qui sont notre modèle, les OneToMany sont tous en LAZY), peut-être avec un type générique de wrapping pour être plus propre.
    Par contre concrètement je ne vois pas trop comment mettre ça en oeuvre, en ce qui concerne la problématique de surcharger les Entity sans que la classe fille ne soit persistée en BD (il me faudrait un genre de @MappedSuperclass mais dans l'autre sens de la relation d'héritage, la surcharge n'étant utile que lors du chargement du modèle complet à partir d'un point d'entrée, dans certains cas d'utilisation).
    Je me demande même si on peut surcharger des annotations comme ça.

    Toute aide est la bienvenue car malgré nos efforts on est à la bourre et le flot de specs de nouvelles fonctionnalités ne montre aucun signe de tarissement

  3. #3
    Membre chevronné
    Avatar de grishka
    Inscrit en
    Janvier 2003
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 285
    Par défaut
    Salut,

    le "join fetch" est performant si on limite à une seule relation 1->N par objet père (à cause du produit cartésien engendré dans le résultat de la requête), ce qui n'est pas ton cas.

    je laisserais le paramètrage en lazy pour l'exploration du graphe via les getter. Avec ta solution d'exploration, tu refais "en dur" ce que Hibernate te permet via le paramétrage (et généralement il ne vaut mieux pas figer le mode de récupération dans le paramétrage, c'est un nid à emmerde). De plus tu te retrouve avec des N+1 select en cascade (et donc n*m*o requêtes suivant la profondeur du graphe), ce qui est difficilement acceptable pour une requête de reporting.

    Je te conseille de composer des requêtes de reporting en HQL en évitant les fetch join et en utilisant les batchs (tu te retrouves donc avec (n/t)*(m/t)*(o/t) *... requêtes, t étant la taille des batchs, les divisions étant arrondies à l'entier supérieur).

    de plus on peut parfois limiter les N+1 selects avec une approche horizontale plutot que verticale du graphe d'objet (exploration en largeur plutot qu'en profondeur) : tu utilises l'opérateur "IN" , puis tu effectues la "jointure" (repeuplement de la hiérarchie) en java.

  4. #4
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 9
    Par défaut
    Merci de ta réponse mais je n'ai pas compris la solution alternative avec ce que tu appelles les "batchs". Tu pourrais me diriger vers un lien qui expliquerait un peu le principe parce que la ca me passe un peu au dessus de la tete

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2007
    Messages
    100
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Janvier 2007
    Messages : 100
    Par défaut
    Bon j'avoue pas avoir tout compris à ton problème, mais est-ce que tu ne pourrais pas te débrouiller avec la méthode Hibernate.initialize(o) (qui force le chargement d'un proxy) ?

  6. #6
    Membre chevronné
    Avatar de grishka
    Inscrit en
    Janvier 2003
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 285

  7. #7
    Membre du Club
    Inscrit en
    Septembre 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 9
    Par défaut
    Citation Envoyé par CharlSka Voir le message
    Bon j'avoue pas avoir tout compris à ton problème, mais est-ce que tu ne pourrais pas te débrouiller avec la méthode Hibernate.initialize(o) (qui force le chargement d'un proxy) ?
    Le problème c'est qu'on veut faire ce que tu dis mais récursivement.

    Exemple: supposons qu'on ait des classes Maitre, Chien, Jouet, MorceauDeJouet.
    On veut charger les Maitre de façon à ce que, sans faire de requête supplémentaire, le client puisse faire maitre.getChiens()[i].getJouet()[i].getMorceauDeJouet()

    Dans notre cas le graphe d'objets est bien plus compliqué que ça, donc on ne peut pas se permettre d'écritre des Hibernate.initialize pour chaque relation explicitement.

Discussions similaires

  1. [RIA Services] Graphes d'objets et includes
    Par anthyme dans le forum Silverlight
    Réponses: 0
    Dernier message: 13/06/2011, 23h35
  2. charger puis exposer des objets avec un ORM
    Par maa dans le forum Général Dotnet
    Réponses: 10
    Dernier message: 11/04/2011, 11h58
  3. Graphe sémantique : objets sémantiques (RFC3)
    Par onjanirina dans le forum Conception (Générale)
    Réponses: 5
    Dernier message: 19/03/2011, 12h17
  4. Graphe d'objet et désallocations
    Par screetch dans le forum C++
    Réponses: 8
    Dernier message: 14/01/2011, 13h35
  5. [Architecture / Services] Graphe d'objets à sauvegarder
    Par mauvais_karma dans le forum Plateformes (Java EE, Jakarta EE, Spring) et Serveurs
    Réponses: 5
    Dernier message: 05/03/2006, 16h07

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