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 :

[hib 3.2.5] Criteria : Pb de lecture apres enregistrement


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 24
    Par défaut [hib 3.2.5] Criteria : Pb de lecture apres enregistrement
    Bonjour à tous,

    Je rencontre un pb tenace sous une application Web Struts/mySql/Hibernate

    Une page d'administration (par exemple) me permet de gérer une table simple (ajout, modification, suppression) via des champs de formulaire.

    si je met à jour un enregistrement, la base MySQL est correctement mise à jour, l'enregistrement est correctement rechargé (via un createCriteria()), et affiché en retour à l'utilisateur.

    L'utilisation d'un bouton "refresh" (qui relance le meme createCriteria() qu'après l'update) me pose de gros pboblèmes :
    De façon aléatoire, ce sont les anciennes valeurs qui sont affichées en retour. Un coup de debug me montre qu'hibernate est alors persuadé que ce sont réellement les données de mon objet.

    Sentant des pb de cache (alors que le cache de 2eme niveau est désactivé), j'ai rajouté quelques options espérant résoudre mon pb, mais sans succès (setFlushMode(), setCacheMode(), session.clear(), setLockMode(), session.refresh()..)

    la je suis vraiment sec.. d'autant plus que ce pb apparait sur d'autres tables dans des circonstances bcp plus géantes (mise à jour de donnée via Ajax, qui du coup semblent ne pas marcher, alors que c'est hibernate qui ne recharge pas réellement les infos depuis la BDD), etc..


    Voici le bout de code en question, ainsi que le mapping hibernate correspondant.

    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
    Configuration c = new Configuration();
    c.setEntityResolver( new HbmEntityResolver());
    c.configure();
    _sessionFactory = c.buildSessionFactory();
    ...
    ...
    session = _sessionFactory.getCurrentSession();
    session.setFlushMode( FlushMode.ALWAYS);
    session.beginTransaction();
    session.setCacheMode(CacheMode.IGNORE);
    session.clear();
    ...
    ...
    Criteria criteria = session.createCriteria(VocalMessage.class);
    criteria
        .add(Restrictions.eq("id", a_vocalMessageId))
        .setLockMode(LockMode.READ);
    VocalMessage curRecord = (VocalMessage) criteria.uniqueResult();
    if(curRecord != null && !Utils.isEmpty(curRecord.getId())) {
          session.refresh(curRecord, LockMode.READ);
    }
    actionForm.setId(curRecord getCode());
    actionForm.setCode(curRecord getCode());
    actionForm.setName(curRecord getDescription());
    actionForm.setMessageId(curRecord getMessageIndex());
    ...
    ...
    session.getTransaction().commit();
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    <hibernate-configuration>
      <session-factory>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
        <property name="default-cascade">persist</property>
     
        <!--second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
    ...
    ...
    <hibernate-mapping  package="com.test.datamodel">
      <class
          name="VocalMessage"
          table="VOCAL_MESSAGE"
          abstract="false"
          dynamic-update="false"
          dynamic-insert="false"
          select-before-update="false"
          polymorphism="implicit"
          lazy="true">
        <id
          name="id"
          type="string"
          access="property"
          unsaved-value="null">
          <column
            name="ID"
            length="10"
          />
          <generator class="assigned"/>
        </id>
        <property
          name="name"
          type="string"
          access="property"
          update="true"
          insert="true"
          lazy="false">
          <column
            name="NAME"
            length="50"
            unique="false"
            not-null="true"
          />
        </property>
        <property
          name="messageId"
          type="string"
          access="property"
          update="true"
          insert="true"
          lazy="false">
          <column
            name="MESSAGEID"
            length="5"
            unique="true"
            not-null="true"
          />
        </property>
      </class>
    </hibernate-mapping>
      </session-factory>
    </hibernate-configuration>
    Si l'un de vous a une piste quelquonque je lui serait eternellement redevable ^__^


    Merci à tous pour votre aide.

    Patrick.

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

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Tout ce code vient de la même méthode ?

    Tu fermes ta session ou jamais ?

  3. #3
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 24
    Par défaut
    Citation Envoyé par fr1man Voir le message
    Tout ce code vient de la même méthode ?
    Salut fr1man,
    Non mon code est eclaté en plusieurs methodes, j'ai fait ici une petite compilation pour simplifier l'ensemble...

    En fait je passe par un jar (dataModel qui gere le pool de connexions).
    De mon coté, je demande au dataModel une nouvelle connexion vi une methode getHibernateSession() :
    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
    	public static Session getHibernateSession() {
    		Session  session = null;
    		try {
    			session = Datamodel.getSessionFactory().getCurrentSession();
    			session.setFlushMode( FlushMode.ALWAYS);
    			session.beginTransaction();
    			session.setCacheMode(CacheMode.IGNORE);
    			session.clear();
    		}
     
    		catch(Throwable err) 
    		{
    			session = null;
    			MLogging.error(new LogData(null, MsgLabel.getLabel("error.bdd")));
    			MLogging.error(new LogData(null,err.getMessage()));
     
    			if(Configuration.isDEBUG()) { err.printStackTrace(); }
     
    		}
    		return session;
    Le dataModel lui fait appel a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Configuration c = new Configuration();
    c.setEntityResolver( new HbmEntityResolver());
    c.configure();
    _sessionFactory = c.buildSessionFactory();
    une fois que j'ai ma session, je travaille dessus (select/insert/update/commit selon les besoins). Les insert/update et chargement des objets sont localisés dans des méthodes spérarées. Je récupère à chaque fois la transaction en cours par un appel à une méthode getCurrentSession() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public static Session getCurrentSession() {
    		Session  session = Datamodel.getSessionFactory().getCurrentSession();
    		if(!session.getTransaction().isActive()) {
    			session.setFlushMode( FlushMode.ALWAYS);
    			session.beginTransaction();
    			session.setCacheMode(CacheMode.IGNORE);
    			session.clear();
     
    		}
    		return session;
    	}

    et en fin d'action Struts, il y a toujours un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    session.getTransaction().commit();
    par contre, effectivement, mes sessions ne sont jamais explicitement fermées, car le pool de connexions hibernate est censé le faire tout seul.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    par contre, effectivement, mes sessions ne sont jamais explicitement fermées, car le pool de connexions hibernate est censé le faire tout seul.
    Ca dépend, tu l'as configuré comment ?

  5. #5
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 24
    Par défaut
    Citation Envoyé par fr1man Voir le message
    Ca dépend, tu l'as configuré comment ?
    Je me suis un peu mélangé tout à l'heure...
    L'appel au SessionFactory().getCurrentSession() doit me retourner la session hibernate du thread courant ou en créer une si elle n'existe pas.
    A cette session est associée un connexion issue du pool de connexion BDD (qui sera géré a terme par Sequoia). Lors du commit(), la connexion est rendue au pool de connexion, et la session hibernate est terminée.

    Le pool de connexion sera géré à terme par sequoia (non actif sur la plateforme de dev)... du coup, je n'ai pas de paramétrage particulier pour mon poll de connexion.

    Voici le contenu de mon fichier hibernate.properties :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    hibernate.connection.driver_class=com.mysql.jdbc.Driver
    hibernate.connection.url=jdbc\:mysql\://localhost/project?autoReconnect\=true
    hibernate.connection.username=xxx
    hibernate.connection.password=xxx
    hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
    hibernate.connection.autocommit=false
    hibernate.connection.release_mode=auto
    hibernate.show_sql=false
    ce que je ne comprend pas, c'est que même si la session hibernate m'était retournée à chaque fois etait la même,
    le fait de faire un session.setCacheMode(CacheMode.IGNORE) et un session.clear() après le beginTransaction() devrait suffire pour obliger hibernate à charger les données depuis la base de données, et non pas les récupérer dans un cache (que je n'ai pas activé..)

    non ?

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Effectivement, le clear devrait vider la session.

    Tu devrais cependant, fermer ta session après le commit de ta transaction.

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

Discussions similaires

  1. Empecher Lecture d'Enregistrement en cours de Modification
    Par toony dans le forum Administration
    Réponses: 4
    Dernier message: 09/12/2009, 11h18
  2. probleme de lecture après ecriture
    Par ing2009 dans le forum Réseau
    Réponses: 1
    Dernier message: 30/04/2009, 19h24
  3. Lecture et enregistrement photo et audio
    Par shakur221 dans le forum Java ME
    Réponses: 4
    Dernier message: 04/06/2008, 11h50
  4. Réponses: 18
    Dernier message: 17/01/2007, 12h49
  5. Valeur null lors de la lecture apres un insert
    Par omlip dans le forum Hibernate
    Réponses: 1
    Dernier message: 07/07/2006, 13h56

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