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 :

Probleme de Synchronisation entre la session hibernate et la base de donnée


Sujet :

Hibernate Java

  1. #1
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut Probleme de Synchronisation entre la session hibernate et la base de donnée
    bonjour tout le monde

    je sais pas c'est j'ai bien choisi le titre de mon sujet , mais voila le probleme que j'ai:
    Dans une page JSP, je liste mes enregistrement de ma base de donnée dans une table. JK'ajoute à ma table une colonne qui affiche pour chaque ligne le mot supprimer.
    Cliquer sur supprimer, c'est envoyer l'id de l'enregistremnt séléctionné à une autre page qui appelle une méthode pour la suppression, et fait un farwarding à ma premiere page.

    voila ma methode de suppression :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public static void deleteClass1(Integer c){
    		Session session=HibernateSessionFactory.currentSession();
    		Transaction tx=session.beginTransaction();
    		Class1 classe=(Class1)session.load(Class1.class,c);
    		session.delete(classe);
    		tx.commit();
    	}
    et voila mon fichier de mapping:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <class name="packClasse1.Class1" table="classe1">
            <id name="idc" column="IdClasse1">
                <generator class="increment"/>
            </id>
            <property name="nomc" column="NomCl"/>
        </class>
    Lorsque ma premiere page est chargé de nouveau par l'action de farwarding, j'ai tout mes enregistrements sauf celui que j'ai supprimer (C'est normal), mais ce qui est n'est pas normal c'est l'erreur qui me sorte lorsque j'actualise ma page (Je clique sur le bouton actualiser de mon browser). :
    cet erreur dit que il y a un objet manquant (C'est l'objet que j'ai supprimé).
    Je crois que cette ne doit pas se produire ? Je suppose qu'il y a un probleme de synchronisation.
    Que pensez vous ? et comment je dois me proceder pour eviter cette erreur?

  2. #2
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    voilà l'erreur qui me sort :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    org.apache.jasper.JasperException: No row with the given identifier exists: [packClasse1.Classe1#3]
    	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:370)
    	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:291)
    	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    et voilà ma page jsp que j'utilise pour l'affichage de mes enregistrement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <body>
        <%
        	List list=Classe1Services.listClasse();
        	request.setAttribute("classes",list);
        %>
        <display:table name="classes">
        	<display:column property="nomc" title="Nom_Classe"/>
        	<display:column paramId="idClasse" paramProperty="idc" href="suppClasse.jsp">Supprimer</display:column>
        </display:table>
      </body>
    et pour le code de lapage qui appelle la methode suppression :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <body>
        <%
        	String id=request.getParameter("idClasse");
        	Classe1Services.deleteClasse(new Integer(id));
        %>
        <jsp:forward page="listeClasses.jsp"></jsp:forward>
      </body>
    Qu'est ce que vous pensez de mon code ?
    autre chose la suppression se fait au niveau de la base de donnée.

  3. #3
    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
    Réponse bête, mais est-ce que le rafraichissement n'appelerait pas ta page de suppression par hasard ?
    Lance ton appli en DEBUG.

  4. #4
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    je m'excuse, j'ai pas bien compris ta reponse?
    Réponse bête, mais est-ce que le rafraichissement n'appelerait pas ta page de suppression par hasard ?

  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
    Quand tu cliques sur le bouton actualiser, est-ce bien la page d'affichage qui est appelée ou la page de suppression ?

  6. #6
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    Bien sur, C'est la page d'affichage.

  7. #7
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    Est ce que ça peut avoir une relation avec ma liste ou je mets mes objets avant de les afficher sur ma table ?

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    548
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 548
    Points : 635
    Points
    635
    Par défaut
    Il faudrait le code de Classe1Services.listClasse() pour savoir

  9. #9
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    Conseil bete mais ca mange pas de pain :

    Met un block try/catch autour de ton code deleteClass1, ca te permettra d'éviter d'avoir un plantage et aussi de fermer proprement la transaction

    Un truc dans le genre
    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
     
    public static void deleteClass1(Integer c){
    		Session session = null;
    		Transaction tx = null;
    		try {
    			session = HibernateSessionFactory.currentSession();
    			tx = session.beginTransaction();
    			Class1 classe = (Class1)session.load(Class1.class,c);
    			session.delete(classe);
    			tx.commit();
    		} catch (Exception e){
    			tx.rollback();
    			System.out.println("Error during deleteClass1 : " + e);
    		} finally{
    			if (session != null) session.close();
    		}
    	}
    En plus, ca te permettra de voir si quand tu appuie sur actualiser, ca ne relancerait pas la fonction de suppression d'un element déja supprimé


    EDIT : code corrigé selon les conseils avisés de la dessous avec un truc vraiment propre et bien tout fermé comme il faut
    Je ne suis pas mort, j'ai du travail !

  10. #10
    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
    Pourquoi refaire un commit dans le finally étant donné que le bloc finally est appelé même en cas d'erreur.
    J'aurais laissé le commit dans le try, et effectivement, rajouté le rollback dans le catch.

  11. #11
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Par contre danzs le finally mieux vaudrait faire un session.close() si la session n'est pas nulle
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  12. #12
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    Citation Envoyé par fr1man
    Pourquoi refaire un commit dans le finally étant donné que le bloc finally est appelé même en cas d'erreur.
    J'aurais laissé le commit dans le try, et effectivement, rajouté le rollback dans le catch.
    Disons que c'est une habitude que j'ai prise de toujours rajouter une fermeture propre de la transaction/session/connection dans une finally même si c'est déjà fermé dans le code (habitude prise suite à une revue de code ou les connections/sessions/transactions étaient fermées de facon stochastiques)
    Mais oui, effectivement, ca sert pas à grand chose... Et autant laisser le commit dans le bloc try et ne pas faire de finally. Ou ne pas faire le commit dans le try et le faire dans le finally.


    EDIT : et oui, aussi rajouter un session.close() dans le finally, rooo... Mais à la base y'avait carrement pas, donc c'est mieux que rien
    Je ne suis pas mort, j'ai du travail !

  13. #13
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    Merci à tous pour vos participations.
    pour le code de ma mthode Classe1Services.listClasse() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public static List listClasse(){
         Session session=HibernateSessionFactory.currentSession();
         Transaction tx=session.beginTransaction();
         List mesClasses=session.createQuery("from Classe1").list();
        session.close();
        return mesClasses;
    }
    les objets que je recupere, je les mets dans une liste (Dans ma page d'affichage)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <%
        	List list=Classe1Services.listClasse();
        	request.setAttribute("classes",list);
        %>
    avec quelle j'alimente ma table(display tag).

  14. #14
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    Conseil : inspire toi du code modifié pour modifier toutes tes methodes qui font des accès à la base de donnée...

    Et pas besoin d'ouvrir une transaction pour une requete qui ne fait que de la lecture des données

    EDIT : @fr1man : Vérification faite : tu m'explique à quoi ca sert d'ouvrir une transaction pour lire les données sachant que le principal interet de la transaction c'est de pourvoir faire un commit ou un rollback ?
    De ce que j'en sais, ca n'a rien de 'necessaire'
    Je ne suis pas mort, j'ai du travail !

  15. #15
    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
    Même quand on ne fait que de la lecture, il faut ouvrir une transaction.

    Voici un lien vers un exeplication de l'auteur d'un bouquin sur Hibernate:
    http://forum.hibernate.org/viewtopic...action+lecture

  16. #16
    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
    L'intérêt d'une transaction n'est pas de faire un commit ou un rollback.
    C'est plutôt d'assurer la cohérence des données durant une unité de travail.

    Si tu n'es pas au sein d'une transaction et que tu lis une donnée deux fois de suite et qu'entre les deux lectures, la base de données à été modifiée, tu n'obtiendras pas le même résultat.

  17. #17
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    Citation Envoyé par fr1man
    L'intérêt d'une transaction n'est pas de faire un commit ou un rollback.
    C'est plutôt d'assurer la cohérence des données durant une unité de travail.

    Si tu n'es pas au sein d'une transaction et que tu lis une donnée deux fois de suite et qu'entre les deux lectures, la base de données à été modifiée, tu n'obtiendras pas le même résultat.
    J'avais du mal à voir l'interet de la chose, mais effectivement, ton exemple est bon. (cela dit, la, il ne fait que lire les données une fois )
    Et la doc le dit aussi
    Database transactions are never optional, all communication with a database has to occur inside a transaction, no matter if you read or write data.
    http://www.hibernate.org/hib_docs/v3...actions-basics

    (me coucherai moins noob ce soir)
    Je ne suis pas mort, j'ai du travail !

  18. #18
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    Je vous remercie beaucoup les amis pour vos interventions!! j'ai appris pas mal de choses de ces descussions.
    Est ce qu'il y a encore des propositions pour mon probleme?

  19. #19
    Membre expérimenté
    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 : 47
    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
    Points : 1 464
    Points
    1 464
    Par défaut
    Bonjour,
    je pense que ton probleme vient du fait de l'utilisation de la methoe load, pour recuperer ton enregistrement. En hibernate 2 (en hibernate 3 je croies que cette method est supprimee), il y a desux facons de recuperer un enregistrement :

    * load => qui renvoie une exception si l'enregistrement n'est pas trouve (c'est ton cas)
    * get => qui renvoie un objet null, si l'enregistrement n'est pas trouve.

    Donc essaie le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Class1 classe = (Class1)session.get(Class1.class,c);
    if (classe != null)
      session.delete(classe);
    Mais bon personnelement je n'aime pas trop cette facon de faire pour supprimer un enregistrement. Ca execute 2 requetes (1 pour la recuperation de l'enregistrement et une pour sa suppression). Quand on veut faire un delete sur plusieurs id, ca peut devenir penalisant pour les performances.

    Je prefere creer ma requete hql de delete et l'executer ensuite. Ca donnerait (en hibernate 3) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Query q = session.createQuery("delete from Class1 where idc = :myIdc");
    q.setInteger("myIdc", c);
    q.executeUpdate();
    Je sais que je l'avais fait aussi en hibernate 2, mais je suis pas sur que c'etait comme ca (a verifier).

    Angelo

Discussions similaires

  1. Annotations Hibernate et schéma Base de données MySQL
    Par bdtatr dans le forum Hibernate
    Réponses: 1
    Dernier message: 08/07/2007, 07h12
  2. Réponses: 2
    Dernier message: 29/04/2007, 19h59
  3. Réponses: 1
    Dernier message: 23/01/2007, 11h06
  4. probleme de virgule dans la mise à jour d'une base de donnée
    Par KAF dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 24/12/2005, 02h18

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