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 :

hibernate : utliser query.list() ou query.iterate()


Sujet :

Hibernate Java

  1. #1
    Nouveau membre du Club
    Inscrit en
    Décembre 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 36
    Points : 25
    Points
    25
    Par défaut hibernate : utliser query.list() ou query.iterate()
    bonjour mes amis,
    j'ai une application web en spring+hibernate+struts. et tout marche trés bien. Mais aprés le déploiment en qlq jours un bug me sort le message : java.lang.OutOfMemoryError.
    aprés une recherche sur internet j'ai trouvé deux astuces :
    - augmenter la mémoire allouée par la JVM
    - optimiser le code en libérant de objets non utilisé pour quels soit supprimer par le Garbage Collector.
    pour la deuxième solution, j'ai examiner le code et j'ai remaque que toutes les requête HQL sont enoyée par le bais d'une méthode qui retourne query.list();.
    donc une liste qui a toutes les objets souhaité à afficher... et je trouve ça non optimal (et si on a 1000000 objets. c'est la panique de la RAM)
    ma question :
    - y a t'elle une différence entre query.list() et query.iterate() dans le sens d'optimisation de la mémoire allouée ?
    merci d'avance

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    C'est à toi de faire une requête suffisamment précise pour ne pas récupérer autant de lignes en une seul fois.
    Tu peux également utiliser un système de pagination.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Décembre 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    Merci pour votre réponse,
    la requête est composée dynamiquement par des critère de recherche définit par l'utilisateur de l'application. autant de plus j'utilise la pagination pour limiter le nbre des lignes à afficher. Mais pour faire cela je devrais stocker tous les objets résultat dans Arraylist en affectant par query.list().
    mais si je fais ça avec l'iterator (qurey.iterate()) ça devra résoudre le problème de la mémoire ?

  4. #4
    Membre actif Avatar de mOuLi
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Points : 257
    Points
    257
    Par défaut
    Attention, l'utilisation de query.iterate() peut considérablement allonger ton temps de traitement (car soumis au syndrome du N+1 select).
    A priori l'utilisation d'itération "scrollable" (ScrollableResults) si ton driver JDBC le tolère serait plus performant.
    Pour plus d'infos, voir la doc d'Hibernate (paragraphes 10.4.1 si Hibernate v3+).

  5. #5
    Nouveau membre du Club
    Inscrit en
    Décembre 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    Merci bien pour votre réponse (une nouvelle piste à creuser )
    seulement une dernière question : est ce que le drivers JDBC d'oracle support "ScrollableResults" ?
    merci

  6. #6
    Membre actif Avatar de mOuLi
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Points : 257
    Points
    257
    Par défaut
    Je n'en sais rien. Il faudrait tester en activant les traces SQL pour voir :
    1/ si ça marche (il est possible qu'une exception soit levée si ce n'est pas supporté par le driver.
    2/ comment ça se passe en terme d'ordres SQL.
    Bon courage

  7. #7
    Nouveau membre du Club
    Inscrit en
    Décembre 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    merci bien
    je vais tester et on va voir

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    j'en profite pour ajouter un petit complément.

    Bon encore une fois je vois le même problème récurent et délicat que sont les fuites de mémoires..

    Je ne suis pas un pro dans ce domaine loin de là, mais comme bcp de développeurs, je me retrouve de temps en temps confronté à ce problème.

    donc je vais pouvoir vous donner mon point de vue..

    alors ta première solution qui consiste à alloué plus de mémoire à la JVM n'est pas pour moi une bonne pratique à effectuer. en effet cela sera efficace mais sur une courte durée car les vrais problèmes de pertes de mémoires sont toujours là. pour moi c comme prendre un placebo..

    ta deuxième solution qui consiste à l'optimisation du code est en effet bcp mieux, mettre tout les objet dont on ne se sert plus à null permet d'aider le fonctionnement du garbage collector et de détruire plus rapidement ces objets inutiles.(donc à plébiciter) les autres types d'optimisation tel qu'utiliser des StringBuilder au lieu de StringBuffer ou encore d'optimiser les requetes SQL etc ne servent pas à grand chose ds les cas de pb mémoires mais plutôt à améliorer les vitesse de traitements.

    pour ta question sur les query.list() et les query.iterate(), je ne connait pas les infos sur les meilleurs cas d'utilisation pour ma part j'utilise des query.list() sans problème apparent. je pense que cela joue plus sur les temps de traitement que sur les questions de mémoires mais je ne connait pas .

    Sinon un des gros gros problème connu de l'utilisation d'hibernate est l'apparition de grosse perte de mémoires du à l'utilisation du jar cglib qui est très instable et possède de nombreuses fuites, ce qui peut aussi donner l''exception "perm space" lorsque l'on recompile de nombreuse fois le code en période de développement ou que l'on redéploie de nombreuse fois l'application
    le mieux est de ne pas utiliser cglib et de l'oublier completement, il existe un mode de fonctionnement d'hibernate qui permet cela.

    pour avoir plus d'info je vous laisse 2 liens:

    le premier sur l'optimisation mémoire (dans ce forum) et le second sur l'optimisation sql:

    http://www.developpez.net/forums/sho...69#post1348469

    http://sqlpro.developpez.com/cours/optimiser/


    si vous avez d'autres liens sur l'optimisation.
    merci d'en faire part je suis preneur

    bon dev.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Décembre 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    Merci escobiz maintentant je voie les choses plus claire

    pour mon cas de mon application j'utilise cglib-2.1.3.jar. Pouvez-vous m'éclaircir davantage sur l'isolation de cglib d'Hibenate ?

    une documentation ou lien sera le bienvenue

    merci d'avance

  10. #10
    Invité
    Invité(e)
    Par défaut
    D'après la doc d'Hibernate:

    pour désactiver l'utilisation de GLIB, mettre à false la propriété
    hibernate.cglib.use_reflection_optimizer
    qui est à true par défault dans le fichier de config d'hibernate


    Disable Hibernates usage of cglib reflection optimizer

    Put the following line in hibernate.properties:

    hibernate.cglib.use_reflection_optimizer=false

    It will make Hibernate start faster since it does not try to build cglib-enhanced objects to access getter/setters.

    Note: It will have in impact on overall runtime performance since Hibernate will be forced to use standard JDK reflection for access. So it is most useful during development. (You will also get better error messages in some situations when the optimizer is disabled

  11. #11
    Nouveau membre du Club
    Inscrit en
    Décembre 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    merci bien
    pour une app web, la config dans le fichier xml de Hibernate est :

    <prop key="hibernate.cglib.use_reflection_optimizer">false</prop>

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

Discussions similaires

  1. cacti pas de data query liste vide
    Par hacbao dans le forum Supervision
    Réponses: 1
    Dernier message: 22/05/2014, 09h06
  2. Réponses: 2
    Dernier message: 13/05/2009, 13h43
  3. [forms 6i] liste + ENTER-QUERY
    Par Magnus dans le forum Oracle
    Réponses: 3
    Dernier message: 23/12/2005, 14h30
  4. [dev-C++]std::list<tree_node<T>*> iterator;
    Par jmv dans le forum Dev-C++
    Réponses: 7
    Dernier message: 06/05/2005, 13h14
  5. faire un Query sur un Query ?
    Par davestar dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/04/2004, 12h30

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