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 :

[Spring & Hibernate] Gestion des sessions Hibernate


Sujet :

Hibernate Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 54
    Points : 39
    Points
    39
    Par défaut [Spring & Hibernate] Gestion des sessions Hibernate
    Bonjour a tous,

    dans un projet, j'utilise Spring 2.5.4 et hibernate 3.2.5. jdk 1.4.

    mon problème est la gestion des sessions avec hibernate

    je récupere en db une personne

    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
    21
    22
     
    public class Person {
           private String lastName;
           private String firstName;
           private Date birthDate;
           ...
           private Set telephone; 
    }
    public class Telephone {
          private int number;
          private String type;
          ....
    }
     
    public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao {
     
               public Person getOneById (int personId) {
                     return getSession().createCriteria(Person.class).add (Restrictions.eq("personId",personId)).uniqueResult();
               }
     
     
    }
    je remonte l'info dans un formulaire updatePerson.jsp
    ou je n'affiche que quelque info modifiable + id personne

    lorsque je fait un submit, dans mon controller spring je récupere la Personne via son id
    je modifie les infos updatée

    ensuite je sauvegarde les donnée en db via cette méthode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void saveOrUpdate (Person person) {
            getSession().saveOrUpdate(person);
    }
    et la j'ai un exeption

    org.springframework.orm.hibernate3.HibernateSystem Exception: Illegal attempt to associate a collection with two open sessions;

    j'ai essayé de modifer ma méthode save or update de cette façon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Session session = getSession();
    session.evict(person);
    session.saveOrUpdate(person);
    sans succès
    car mon objet se trouve dans la session crée lors du getPersonById et non celle que j'utilise dans mon saveOrUpdate

    comment faut il faire pour garder la même session hibernate pour chaque appelle client/serveur ?

    est ce que ma façons d'écrire les dao est correcte ?

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Salut,

    Tu as apparemment deux sessions d'ouverte.

    Je chercherais dans deux directions (il y en a surement d'autres):

    - Tu n'utiliserais pas un mécanisme OSIV (Open Session In View) qui utiliserait une session différente dans ta vue pour charger des associations de ton objet ?

    - Lors de la sauvegarde de l'élément en base, tu passes par le même mécanisme pour récupérer la session : getSession() d'HibernateDaoSupport ?

    Lorsque je fait un submit, dans mon controller spring je récupere la Personne via son id je modifie les infos updatée
    Comment tu récupérés la personne ici ? Toujours avec getOneById() ?
    Ils flottent tous en bas

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Bonjour,

    oui j'ai bien 2 sessions ouverte,

    non, je n'utilise pas le openSessionInViewFilter

    j'utilise toujours getSession()

    mon Dao

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao {
     
               public Person getOneById (int personId) {
                     return getSession().createCriteria(Person.class).add    
                                      (Restrictions.eq("personId",personId)).uniqueResult();
               }
     
               public void saveOrUpdate (Person person) {
                     getSession().saveOrUpdate (person);
               }
     
    }
    dans mon controller

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    public ModelAndView onSubmit (HttpServletRequest request, 
    			HttpServletResponse response, Object command, 
    			BindException exception) throws Exception {
     
                 Person updatedPerson = (Person)command;
                 Person person = personDao.getOneById (updatedPerson.getPersonId());
     
                 // merge de updatedPerson et Person
                 ....
     
                 personDao.saveOrUpdate (person);
    }
    j'ai trouvé 2 solutions

    la première est d'avoir un champ

    private static Session session;

    dans mon Dao

    la deuxième est de stocker toutes les infos de person dans des input hidden
    ainsi j'évite la requete pour aller rechercher les infos en db

    est t-il possible de faire autrement ?

    merci.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Salut,

    Le problème vient de la. Tu n'as pas droit d'en attacher à 2 session d'ouvertes. Surement à cause d'un risque d'incohérence d'état : la collection pourrait être amenée à avoir un état différent dans les deux sessions.

    la première est d'avoir un champ

    private static Session session;

    dans mon Dao
    Si ta session est partagée par les méthodes de ton dao et qu'un de tes dao essuie un rollback, ta session risque d'etre capoute pour les autres méthodes de ton dao.

    La deuxième est de stocker toutes les infos de person dans des input hidden
    ainsi j'évite la requete pour aller rechercher les infos en db
    Arf, Si t'as bcp d'info, ca devient galère.

    est t-il possible de faire autrement ?
    Certainement.

    Sur la doc de getSession() D'HibernateDaoSupport, on peut lire ca :
    Either rely on a thread-bound Session or use it in combination with releaseSession(org.hibernate.Session).
    Par défaut, il me semble que le contexte de l'actuel session est de type thread dans Hibernate.
    Si tu l'as valorisé à autre chose comme JTASessionContext, c'est peut-être une piste à creuser.

    Dans ts les cas, tu peux rechercher dans ton fichier de conf Hibernate la propriété current_session_context_class.
    Si la valeur n'es pas 'thread' ou si tu ne la voit pas, ajoute ou modifie la propriété pour qu'elle soit ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <property name="current_session_context_class">thread</property>
    Sinon si ca marche toujours pas, j'essayerais de passer par getSessionFactory().getCurrentSession() au lieu de getSession().
    La session récupérée dépend de la valeur de current_session_context aussi.

    Si le current_session_context est de type thread, il y a des chances que ca marche si les deux requêtes hibernate se déroulent au sein du même thread d'exécution de ton conteneur. Et vu la description de l'anomalie, jai l'impression que c'est le cas.
    Ils flottent tous en bas

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    slt,

    j'ai ajouter, dans mon LocalSessionFactoryBean, cette propriété

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <property name="hibernateProperties">
           <props>
               ...
               <prop key="hibernate.current_session_context_class">thread</prop>
           </props> 
    </property>
    liste des proppriétés d'hibernate
    http://www.dil.univ-mrs.fr/~massat/d...iguration.html

    j'ai remplacé le getSession() par getSessionFactory().getCurrentSession()

    j'ai eu une autre erreur : HibernateException: createCrtiteria is not valid without active transaction

    j'ai donc modifier la création du spring-bean de cette façon

    old config
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            <bean id="personDao"
    		class="mypackage.dao.impl.personDaoImpl">
    		<property name="sessionFactory" ref="sessionFactory" />		
    	</bean>
    par

    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
    21
    22
    23
    24
    25
    26
    27
    28
     
           <bean id="transactionManager" 	class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory">
    			<ref local="sessionFactory" />
    		</property>
    	</bean>
     
            <bean id="personDaoTarget"
    		class="mypackage.dao.impl.personDaoImpl">
    		<property name="sessionFactory" ref="sessionFactory" />		
    	</bean>
     
            <bean id="personDao"            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager">
    			<ref bean="transactionManager" />
    		</property>
    		<property name="target">
    			<ref bean="personDaoTarget" />
    		</property>
    		<property name="proxyTargetClass">
    			<value>true</value>
    		</property>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRED</prop>
    			</props>
    		</property>
    	</bean>
    et, j'ai toujours la même erreur
    HibernateException: createCrtiteria is not valid without active

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Arf.
    J'ai jamais déclaré les transactions avec Spring avec TransactionProxyFactoryBean. Donc, je sais pas trop.

    Je passe toujours par le namespace Spring tx, c'est bien plus simple.
    http://static.springsource.org/sprin...ansaction.html
    Ils flottent tous en bas

Discussions similaires

  1. @Transactional et gestion des sessions hibernate
    Par verbose dans le forum Spring
    Réponses: 7
    Dernier message: 20/10/2013, 17h03
  2. Gestion des session Spring Hibernate
    Par aminedeveloppement dans le forum Hibernate
    Réponses: 0
    Dernier message: 20/04/2013, 23h58
  3. Hibernate/Spring : gestion des sessions
    Par herve91 dans le forum Hibernate
    Réponses: 5
    Dernier message: 13/05/2010, 11h15
  4. Gestion des sessions Hibernate
    Par schumi2k2 dans le forum Hibernate
    Réponses: 5
    Dernier message: 31/03/2009, 17h44
  5. Hibernate et la gestion des sessions
    Par ruff15 dans le forum Hibernate
    Réponses: 5
    Dernier message: 15/10/2008, 14h08

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