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

Spring Java Discussion :

[Spring & Hibernate] Problème de session


Sujet :

Spring Java

  1. #1
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut [Spring & Hibernate] Problème de session
    Bonjour !

    J'ai un problème avec l'intégration d'hibernate dans spring.
    J'utilise Spring en tant qu'IOC, AOP mais surtout Template pour hibernate (ce qui pose problème ici).
    Petite explication préliminaire du logiciel :
    J’ai 2 entity : User et Message, un User a un certain nombre de message envoyé et un certain nombre de message reçu.
    En effet lorsque je fais une récupération de données via un DAO CRUD classique de Spring la session est fermée dès que l'opération est finie…
    Et si je veux accéder a d’autre entity lié par une relation OneToMany par exemple et bien j’ai l’erreur "classique" :

    GRAVE: failed to lazily initialize a collection of role: hermes.model.dao.entities.User.sendedMessages, no session or session was closed

    Apres pas mal de recherche j’ai compris que ca venais du "Lazy" utilisé par hibernate qui permet de récupérer des données en relation "plus tard" mais seulement quand la session est encore ouverte !

    Dans ces recherches j’ai trouvé 3 solutions :

    - Mettre lazy à off : Hors de question pour des raisons évidente de performances.
    - Mettre des lignes supplémentaires dans le Web.xml pour "binder" un servlet a une session : Helas je ne l’utilise pas dans un servlet, donc il faut que je trouve autre chose.
    - Créer des fonctions spécifique (ie je leur dit que je veux récupérer les entity lié a la récupération du premier entity) dans mon DAO CRUD qui vont exécuter un MonEntity.getMaListDAutreEntity().size() : Je trouve ça très crade et en plus je comprends pas mais cela ne marche pas mieux…

    Bref si vous avez des solutions ? Je vous en remercierai beaucoup !

    Je vous joins un peu de source :

    DAO avec size :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	public User getUser(int id) {
    		User user = (User)getHibernateTemplate().get(User.class, id);
    		user.getReceiptedMessages().size();
    		user.getSendedMessages().size();
    		return user;
    	}
    DAO sans size :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	public User getUser(int id) {
    		User user = (User)getHibernateTemplate().get(User.class, id);		return user;
    	}
    Code client :

    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
    		BeanFactory factory = SpringBeanFactory.getBeanFactory();
    		DAOUserImpl daoUser = (DAOUserImpl)factory.getBean("daoUser");
    		DAOMessageImpl daoMsg = (DAOMessageImpl)factory.getBean("daoMessage");
     
    		User u1 = daoUser.getUser(1);
    		User u2 = daoUser.getUser(2);
     
    		Message msg = new Message();
    		msg.setContents("Salut ca boom ?");
    		msg.setTitle("Yo");
    		msg.setSender(u1);
    		msg.setRecepient(u2);
     
    		daoMsg.saveMessage(msg);
     
    		User user = daoUser.getUser(1); 
     
    		Set<Message> messages = user.getSendedMessages();
    		for (Message message : messages) //l’erreur est ici
    			System.out.println(message.getContents());
    Merci

  2. #2
    Membre à l'essai
    Inscrit en
    Juillet 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 12
    Points : 13
    Points
    13
    Par défaut
    Pour remédier a ce problème, j'ai utilisé le le filtre open in view qui permet de maintenir la session ouverte.
    Pour l'utiliser il faut d'abord ajouter la déclaration dans le web.xml :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <filter>
    		<filter-name>hibernateFilter</filter-name>
    		<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    		<init-param>
    		<param-name>sessionFactoryBeanName</param-name>
    		<param-value>mySessionFactory</param-value>
    		</init-param>
    			<init-param>
    			<param-name>singleSession</param-name>
    			<param-value>false</param-value>
    		</init-param>
    	</filter>
    puis il faut ensuite creer des proxys sur tes objets métiers pour qu'ils implémentent le filtre : dans ton fichier de config Spring, tu modifies les constructeurs de ton objet en ObjetTarget, et tu crées le proxy comme ce-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <bean id="ObjetTarget"
    		class="...">
    		<property name="sessionFactory" ref="mySessionFactory" />
    	</bean>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <bean id="Objet"
    		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="myTransactionManager" />
    		<property name="target">
    			<bean ref="ObjetTarget">
    		</property>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRED</prop>
    			</props>
    		</property>
    	</bean>

  3. #3
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut
    Merci

    Mais comme je l'ai dis dans mon premier message : je ne veux pas que cela passe par un binding sur un servlet... il me faut un systeme plus générique que je pourrais utiliser avec n'importe quel type de client (client lourd par exemple)

  4. #4
    Membre à l'essai
    Inscrit en
    Juillet 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 12
    Points : 13
    Points
    13
    Par défaut
    Oops c'est vrai, peut etre que tu trouveras des réponses dans ce sujet ...
    http://www.developpez.net/forums/sho...rnate+template
    (oui je sais le sujet de base c'est les web applications, mais l'utilisation du ThreadLocal n'est pas spécifique d'une appli web nan ?)

  5. #5
    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
    Tu peux charger les données (collections) dont tu as besoin par l'intermédiaire d'une requête HQL avec l'attribut fetch join, quand tu récupères ton objet principal.
    Tu remplaces donc le load standard par une requête HQL.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 258
    Points : 171
    Points
    171
    Par défaut
    Bonjour,

    Je suis confronté au même problème avec Spring.
    Plantage du Lazy car session fermée au moment de l'accès.

    Y a t-il pas un autre moyen que de faire des fetch join ? car si le modèle de données est compliqué cela devient vite pénible.

    Je développe en RCP.

    Si qqu'un peut me donner un coup de main.

  7. #7
    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
    Tu peux aussi utiliser :
    - Criteria, toujours avec l'option de chargement FETCH
    - Hibernate.initialize() pour charger tes collections

Discussions similaires

  1. [Data] Problème Spring et Hibernate
    Par dany.bill dans le forum Spring
    Réponses: 5
    Dernier message: 06/07/2011, 18h08
  2. Spring +tapestry+hibernate : problème déploiement projet
    Par amadoulamine1 dans le forum Spring Web
    Réponses: 1
    Dernier message: 25/02/2011, 10h01
  3. Réponses: 17
    Dernier message: 29/12/2008, 10h29
  4. problème de session Hibernate
    Par Smix007 dans le forum Hibernate
    Réponses: 6
    Dernier message: 11/12/2006, 14h29

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