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 :

Problème de mise à jour avec tables liées


Sujet :

Hibernate Java

  1. #1
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    219
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 219
    Points : 66
    Points
    66
    Par défaut Problème de mise à jour avec tables liées
    Bonjour, j'ai un problème avec l'update de tables relationnelles. j'ai le schéma suivant dans Mysql 5 :

    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
    CREATE TABLE IF NOT EXISTS `employe` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `nom` varchar(20) DEFAULT NULL,
      `prenom` varchar(20) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
     
    CREATE TABLE IF NOT EXISTS `employe_metier` (
      `id_employe` int(11) NOT NULL,
      `id_metier` int(11) NOT NULL,
      PRIMARY KEY (`id_employe`,`id_metier`),
      KEY `id_employe` (`id_employe`),
      KEY `id_metier` (`id_metier`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
     
    CREATE TABLE IF NOT EXISTS `metier` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `libelle` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
     
    ALTER TABLE `employe_metier`
      ADD CONSTRAINT `employe_metier_ibfk_1` FOREIGN KEY (`id_employe`) REFERENCES `employe` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE,
      ADD CONSTRAINT `employe_metier_ibfk_2` FOREIGN KEY (`id_metier`) REFERENCES `metier` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE;
    Le code Hibernate généré par Netbeans 7.1 :

    hibernate.reveng.xml

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd">
    <hibernate-reverse-engineering>
      <schema-selection match-catalog="interventions"/>
      <table-filter match-name="employe_metier"/>
      <table-filter match-name="employe"/>
      <table-filter match-name="typetravaux"/>
      <table-filter match-name="intervention"/>
      <table-filter match-name="intervention_employe"/>
      <table-filter match-name="metier"/>
    </hibernate-reverse-engineering>
    employe.hbm.xml

    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
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 26 juin 2012 13:58:33 by Hibernate Tools 3.2.1.GA -->
    <hibernate-mapping>
        <class name="com.menehould.interventions.bean.Employe" table="employe" catalog="interventions">
            <id name="id" type="java.lang.Integer">
                <column name="id" />
                <generator class="identity" />
            </id>
            <property name="nom" type="string">
                <column name="nom" length="20" />
            </property>
            <property name="prenom" type="string">
                <column name="prenom" length="20" />
            </property>
            <set name="interventions" inverse="false" table="intervention_employe">
                <key>
                    <column name="id_employe" not-null="true" />
                </key>
                <many-to-many entity-name="com.menehould.interventions.bean.Intervention">
                    <column name="id_intervention" not-null="true" />
                </many-to-many>
            </set>
            <set name="metiers" inverse="false" table="employe_metier">
                <key>
                    <column name="id_employe" not-null="true" />
                </key>
                <many-to-many entity-name="com.menehould.interventions.bean.Metier">
                    <column name="id_metier" not-null="true" />
                </many-to-many>
            </set>
        </class>
    </hibernate-mapping>
    metier.hbm.xml

    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
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 26 juin 2012 13:58:33 by Hibernate Tools 3.2.1.GA -->
    <hibernate-mapping>
        <class name="com.menehould.interventions.bean.Metier" table="metier" catalog="interventions">
            <id name="id" type="java.lang.Integer">
                <column name="id" />
                <generator class="identity" />
            </id>
            <property name="libelle" type="string">
                <column name="libelle" />
            </property>
            <set name="interventions" inverse="true">
                <key>
                    <column name="metier" not-null="true" />
                </key>
                <one-to-many class="com.menehould.interventions.bean.Intervention" />
            </set>
            <set name="employes" inverse="false" cascade="save-update" table="employe_metier">
                <key>
                    <column name="id_metier" not-null="true" />
                </key>
                <many-to-many entity-name="com.menehould.interventions.bean.Employe">
                    <column name="id_employe" not-null="true" />
                </many-to-many>
            </set>
        </class>
    </hibernate-mapping>
    J'explique le problème : quand je mets à jour l'intitulé d'un métier, il disparaît de la relation employé / métier : l'enregistrement disparaît de la table employe_metier. J'ai vérifié après la mise à jour de l'intitulé du métier, il garde pourtant le même id. Pourquoi l'enregistrement disparaît de la table relationnelle ? Je n'arrive pas à comprendre, un problème dans mon mapping ?

  2. #2
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    je ne vois rien de particulier dans ton mapping, tu pourrais donner le code où tu effectues tes changements ?
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  3. #3
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    219
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 219
    Points : 66
    Points
    66
    Par défaut
    C'est une classe d'action Struts 2, voici la méthode concernée on ne peut plus simple :

    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
    public String saveOrUpdate()
        {
            try
            {
                Session session = HibernateUtil.getSession();       
                session.saveOrUpdate(metier);
                Transaction tx = session.beginTransaction();
     
                try
                {           
                    tx.commit();
                }
     
                catch(HibernateException e)
                {
                    addActionError(e.getMessage());
                    tx.rollback();
                } 
            }
     
            catch(HibernateException e)
            {
                addActionError(e.getMessage());
            }
     
            catch(Exception e)
            {
                addActionError(e.getMessage());
            }
     
            if(hasFieldErrors())
            {
                return ERROR;
            }
     
            return SUCCESS;
     
        }
    J'ai le même problème avec une relation intervention <=> employe
    Est ce que c'est le saveOrUpdate qui causerait le problème ? Devrais je faire une méthode save et une méthode update ? Pourtant je ne vois rien de particulier au niveau de ma base, l'enregistrement de l'entité métier garde le même id et les champs concernés sont bien à jour, mais les enregistrements avec l'id mis à jours sont supprimés de la table relationnelle. Peut être un saveOrUpdate supprime t'il d'abord l'enregistrement pour le réinsérer avec le même id ? Avec le cascade cela expliquerait le problème.

  4. #4
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    essayes d'afficher les requêtes effectuées
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <property name="hibernate.show_sql">true</property>
    ça devrait te montrer quelles requêtes sont effectuées depuis hibernate

    je n'ai pas pu reproduire le problème sur mon installation de test, serait-ce ta base de données qui gère les cascades bizarrement ?
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  5. #5
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    219
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 219
    Points : 66
    Points
    66
    Par défaut
    C'est bien ce que je pensais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INFO: Hibernate: update interventions.metier set libelle=? where id=?
    INFO: Hibernate: delete from employe_metier where id_metier=?
    La requête "update interventions.metier" est totalement tordue, l'objet "interventions" ne devrait rien à voir là-dedans... Cela devrait être simplement "update metier"

  6. #6
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    même avec saveorupdate je n'ai pas de problèmes...

    d'où provient ton objet metier avant la sauvegarde ?
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  7. #7
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    219
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 219
    Points : 66
    Points
    66
    Par défaut
    Voici la méthode associée au formulaire de mise à jour appelée via l'url http://.../edit.do?metier.id=...

    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
    public String load()
        {
            try
            {
                Session session = HibernateUtil.getSession();       
                setMetier((Metier)session.load(Metier.class, getMetier().getId()));
            }
     
            catch(HibernateException e)
            {
                addActionError(e.getMessage());
            }
     
            catch(Exception e)
            {
                addActionError(e.getMessage());
            }
     
            if(hasFieldErrors())
            {
                return ERROR;
            }
     
            return SUCCESS;
     
        }
    Je ne vois vraiment pas ce qui cloche, c'est on ne peut plus simple...

  8. #8
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    hum le load ne charge pas les collections il me semble...
    essaye de remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setMetier((Metier)session.load(Metier.class, getMetier().getId()));
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setMetier((Metier)session.get(Metier.class, getMetier().getId()));
    ?
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  9. #9
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    219
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 219
    Points : 66
    Points
    66
    Par défaut
    Aucun changement. J'ai toujours utilisé session.load sans problème, en revanche c'est la première fois que je travaille avec Mysql et des clés étrangères. J'ai l'habitude d'utiliser MSSQL sans tables liées il y a donc peut être une subtilité que je ne maîtrise pas à ce niveau.

  10. #10
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    et de mon côté j'ai toujours travaillé avec mysql et des clés étrangères, avec des collections en pagaille sans jamais rencontrer ce genre de problèmes...

    hum voyons ce que dit ton hibernate.cfg.xml ?
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  11. #11
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    219
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 219
    Points : 66
    Points
    66
    Par défaut
    le voici :

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
      <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/interventions?autoReconnect=true</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.show_sql">true</property>
        <mapping resource="com/menehould/interventions/bean/Typetravaux.hbm.xml"/>
        <mapping resource="com/menehould/interventions/bean/Intervention.hbm.xml"/>
        <mapping resource="com/menehould/interventions/bean/Metier.hbm.xml"/>
        <mapping resource="com/menehould/interventions/bean/Employe.hbm.xml"/>
      </session-factory>
    </hibernate-configuration>

  12. #12
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    bon ben je n'ai pas pu reproduire ton problème... à part en effaçant explicitement les relations avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    metier.getEmployes().clear();
    le fait qu'hibernate efface de lui-même la relation indique qu'à un moment le set de ton objet metier est vidé, maintenant pour quelle raison... à priori ce n'est pas dans le code que tu as posté...
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

Discussions similaires

  1. [AC-2010] Mise à jour de tables liées - Problème avec RefreshLink
    Par zoopsys dans le forum VBA Access
    Réponses: 6
    Dernier message: 24/09/2012, 17h29
  2. Erreur de mise à jour de table liée
    Par tom_ibonia dans le forum Access
    Réponses: 1
    Dernier message: 19/10/2006, 10h52
  3. Problème de mise à jour avec COUNT
    Par chacalito dans le forum Oracle
    Réponses: 2
    Dernier message: 16/10/2006, 11h08
  4. problème de mise à jour de table
    Par captainamerica75 dans le forum Access
    Réponses: 5
    Dernier message: 04/07/2006, 22h14
  5. Mise à jour des tables liées + TIMESTAMP
    Par Homegrown dans le forum Access
    Réponses: 11
    Dernier message: 25/04/2005, 21h52

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