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 :

getSession / getHibernateTemplate [Core]


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2007
    Messages : 71
    Par défaut getSession / getHibernateTemplate
    Bonjour à tous,

    après vous avoir un peu laissé tranquille, je reviens avec une question qui est en train de me plomber ma semaine : vaut-il mieux utiliser getSession() ou getHibernateTemplate() (dans des DAOs héritant de HibernateDAOSupport) ? Et cela a-t-il une influence sur l'utilisation du lazy-loading ?

    Je m'explique : je travaille sur un projet de Web Services utilisant Hibernate pour le mapping à la base. J'ai pu activer le lazy-loading sur certaines collections, mais d'autres résistent encore et toujours à l'envahisseur (Erreur LazyInitializationException : connection closed ou autre).

    Après m'être documenté sur Internet, et relu un peu tout le code du projet, je me suis rendu compte que nous utilisions beaucoup de getHibernateTemplate(). En en remplaçant un par getSession() j'ai réussi à utiliser le lazy-loading sur une nouvelle collection. J'ai donc voulu tous les remplacer, mais j'ai de nouvelles erreurs qui arrivent en pagaille ("illegal attemp to collection" ou "trying to attach a collection to two different sessions")...

    Dans cette dernière erreur, je dois avouer que le "2 sessions différentes" me fait assez peur, étant donné que je pensais travailler dans une seule et unique session ouverte grâce à classe OpenSessionInViewFilter dans le fichier web.xml.

    Si quelqu'un voulait bien m'expliciter un peu plus le rôle de chaque fonction, et laquelle utiliser pour utiliser le lazy-loading, je lui en serait mille fois redevable.

    Merci d'avance,
    MiniMarch

  2. #2
    Membre Expert
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Par défaut
    Bonjour MiniMarch,
    juste pour préciser, apperement tu utilises Spring pour gérer les session hibernates. En ce qui me concerne je n'ai jamais utilisé le getHibernateTemplate.
    J'utilise toujours getSession. getSession utilise la config que tu as mis dans ton fichier de conf Spring, plus exatctement le setter transactionAttributes de TransactionProxyFactoryBean.

    J'utilise PROPAGATION_REQUIRED comme propriété pour utiliser la meme session hibernate pour executer plusieurs requetes. J'ai l'impression que tu as une propriété autre que PROPAGATION_REQUIRED (REQUIRED_NEW?) pour qu'il ouvre un autre session.

    OpenSessionInViewFilter signifie qu'il ouvre a chauqe debut de request une session et la ferme a la fin. Avec un Web Service je ne l'ai jamais fait, peut etre que ca peut etre un probleme (voir le scope du web service)? Peut etre devrais tu deja tester sans Web Service. (Utilises par exemple DWR pou tester rapidement tes services sans passer par la couche SOAP).

    Je t'avoues que je n'aime pas trop la solution OpenSessionInViewFilter. Moi je prefere la solution ThreadLocal. Ca permet d'eviter un fort couplage avec Hibernate. Dans Spring, il faut utiliser org.springframework.orm.hibernate3.LocalSessionFactoryBean

    Enfin le mode lazy, apperement tu l'utilises avace abondance, mais je te conseille de l'utiliser le moins possible. Car tu peux rapidement ramene toutes la base pour recuperer quelques infos. Et meme si au debut tu fais attention, quand le projet va etre maintenu (par un autre developpeur qui ne connait pas les problemetaiques de lazy-loading), on peut faire cetet erreur.

    J'espere que mes infos pourront t'aider

    Angelo

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2007
    Messages : 71
    Par défaut
    Merci bien Angelo, j'y vois déjà un poil plus clair.

    J'utilise effectivement Spring pour les sessions Hibernate. Quoique là, j'ai maintenant un doute après avoir lu le thread suivant http://www.developpez.net/forums/sho...d.php?t=251303 .

    En effet, j'ai effectivement un sessionFactory de configuré dans mon fichier de config applicationContext :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
         <property name="configLocation">
              <value>classpath:hibernate.cfg.xml</value>
         </property>
    </bean>
    en revanche dans le code d'une classe héritant de HibernateDAOSupport, je fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.getSession().maFonction()
    et non :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.getSessionFactory().getCurrentSession().maFonction();
    Y a-t-il une différence ? Est-ce que j'ai mélangé un peu toutes les solutions possibles (et dont tu fais d'ailleurs le tour) ?

    Tu parles d'option PROPAGATION_REQUIRED à configurer quelque part. Mais je ne trouve ni cette valeur ni l'autre dans tout mon projet. Est-ce qu'on doit la configurer au niveau de Hibernate ou de Spring ?

    En revanche, pour le mode Lazy, je ne comprend pas ta réticence (ou je me suis peut-être mal exprimé dans mon message).
    Je veux activer le mode lazy justement pour éviter de remonter toutes les informations de la base (option par défaut sous hibernate 3). Seulement, étant donné, que j'ai des problèmes de session, jusqu'à présent j'ai mis toutes les options lazy à FALSE, que je veux désormais repasser à TRUE/PROXY une fois les problèmes de session résolus.

    MiniMarch

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2007
    Messages : 71
    Par défaut
    Bon, concernant la valeur PROPAGATION_REQUIRED, je viens de progresser un peu : j'ai vu qu'elle devait être précisée pour les transactions. Là où le bas blesse, c'est que j'ai effectivement un transaction manager de défini (voir ci-dessous), mais que ce bean n'est utilisé nul part.

    Configuration du transaction manager :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
         <property name="sessionFactory">
              <ref bean="sessionFactory" />
         </property>
    </bean>
    Est-ce normal ?

    Au risque de faire un amalgame entre les transactions Hibernate et MySQL (est-ce les mêmes ?), notre base actuelle ne supporte pas les transactions.

    Je précise que j'ai repris le projet en cours, et que je me suis formé à Spring et Hibernate dessus. Il est donc possible que j'ai loupé des choses, que les configurations étaient mal faites ou que je ne sois pas au point du tout sur les technos. Il est donc possible (comme je le disais précédemment) que différentes solutions soient mélangées et que je les confonde.

    Merci d'avance à vous pour toutes vos réponses.

  5. #5
    Membre Expert
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Par défaut
    Je n'ai jamais implemente OpenSessionInViewFilter dans une vrai application mais j'ai lu de la doc sur ce pattern, qui je t'avoues ne me plait pas trop pour les raisons suivantes :
    • l'ouverture de la session se fait tout au long de l'appel du Web Service. Par exemple lors de la serialisation/deserialisation des messages SOAP, la session est ouverte alors que la session n'est plus ouverte.
    • si une exception est lance dans l'un des services (ex : NullPointerException), il se peut que la session ne soit pas ferme apres cette erreur grave.


    Concernant le mode lazy, le risque est de se retrouver avec n+1 requetes a executes. Ex : un bean User a un getter roles en lazy qui permet de recuperer la liste des roles d'un user. Imaginons que l'on souhaite recuperer la liste des user avec leur liste de roles, on se retrouve a executer 1 requetes + n requetes (pour recuperer les roles de chaque ligne du user).

    Moi je prefere faire 2 mappings ou copier les Bean dans des DTO (mais bon je ne vais pas m'etendre sur le sujet).

    Concernant ton problème, c'est difficle de t'aider car je n'ai jamais mis en oeuvre OpenSessionInViewFilter. Mais j'ai l'impression que tu ne peux pas utiliser de transactionManager (defini dans spring) avec OpenSessionInViewFilter. J'ai l'impression que ca se parametre dans le web.xml.

    Il ya un paramètre singleSession"="false" d'apres cette doc.

    Desole de ne pas pouvoir t'aider plus.

    Angelo

  6. #6
    Membre Expert
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Par défaut
    Pardon je me suis trompé :

    l'ouverture de la session se fait tout au long de l'appel du Web Service. Par exemple lors de la serialisation/deserialisation des messages SOAP, la session est ouverte alors que la session n'est plus utilisée.
    Angelo

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/07/2009, 09h40
  2. Réponses: 3
    Dernier message: 17/11/2008, 20h05
  3. getHibernateTemplate.get() récupe pas tout !
    Par gazier20 dans le forum Hibernate
    Réponses: 1
    Dernier message: 18/06/2007, 09h30
  4. [Data] probleme avec getHibernateTemplate.find()
    Par Tauros_king dans le forum Spring
    Réponses: 2
    Dernier message: 22/03/2007, 11h05
  5. [Struts][nested]request.getSession().getAttribut()
    Par Invité dans le forum Struts 1
    Réponses: 5
    Dernier message: 26/04/2006, 10h42

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