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 :

Java & hibernate


Sujet :

Hibernate Java

  1. #1
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut Java & hibernate
    Bonjour,

    Je me lance sur Hibernate !!! Tout se passe bien. J'ai quand même un problème assez important à résoudre.

    J'utilise une base de données MySQL 5. J'ai 2 tables : Ressource et Niveau. J'ai une clé étrangère car, une ressource possède un et un seul niveau.

    Lorsque je veux insérer un niveau tout se passe bien. Mais lorsque je veux ajouter une ressource ... POBLEME ...

    Voici mon fichier de mapping :
    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">
     
    <hibernate-mapping package="com.simecom.planning.pojo">
    	<class name="Ressource" table="ressource">
    		<id name="identifiant" column="ID_RES">
    			<generator class="increment"/>
    		</id>
    		<property name="matricule" column="Matricule" />
    		<property name="nom" column="NomR" />
    		<property name="prenom" column="PrenomR" />
    		<property name="motDePasse" column="MDPR" />
     
    		<!--Champ de type Niveau-->
           <one-to-one name="leniveau" class="Niveau" cascade="none" constrained="true"></one-to-one>
    	</class>
     
     
    	<class name="Niveau" table="niveau">
    		<id name="codeNiveau" column="CodeNiv">
    			<generator class="increment"/>
    		</id>		
    		<property name="libelle" column="LibelleNiv" />		
    	</class>
     
    </hibernate-mapping>


    Dans ma classe ressource j'ai cette propriété : private Niveau leniveau;

    Le problème est lorsque j'essaie d'insérer une ressource suite à cette commande :

    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
         Ressource res = new Ressource();
         res.setMatricule("?");
         res.setNom("?");
         res.setPrenom("?");
         res.setMotDePasse("?");
         res.setLeniveau(?);
         session.save(res);[/I]
     
    (Les ? sont des données mais confidentielles ... )
     
     Le souci c'est que lorsque je fais le "save" en base, dans la table ressource, il attend l'identifiant et dans mon code, je lui passe un objet Niveau mais, je ne sais pas comment faire !!!!
     
     L'erreur renvoyée est :
     
    [I]Hibernate: insert into planning.ressource (Matricule, NomR, PrenomR, MDPR, ID_RES) values (?, ?, ?, ?, ?)
    15:44:10,977  WARN JDBCExceptionReporter:71 - SQL Error: 1452, SQLState: 23000
    15:44:10,977 ERROR JDBCExceptionReporter:72 - Cannot add or update a child row: a foreign key constraint fails (`planning/ressource`, CONSTRAINT `FK_Ressource_Niveau` FOREIGN KEY (`ID_NIVEAU`) REFERENCES `niveau` (`CodeNiv`))
    15:44:10,993 ERROR AbstractFlushingEventListener:300 - Could not synchronize database state with session
    org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
    	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:202)
    	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
    	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
    	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
    	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
    	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
    	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    	at com.simecom.planning.test.Test.main(Test.java:70)
    Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`planning/ressource`, CONSTRAINT `FK_Ressource_Niveau` FOREIGN KEY (`ID_NIVEAU`) REFERENCES `niveau` (`CodeNiv`))
    	at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:665)
    	at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
    	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
    	... 8 more

  2. #2
    BsT
    BsT est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 72
    Par défaut
    Hello,

    j'ai l'impression que ton objet Niveau n'est pas enregistrer dans la base.

    As tu dans ton code :

    session.save(niveau) avant session.save(ressource) ?

    Ps : des valeurs comme "Dupont", "Toto", 111111 permettraient d'améliorer la lisibilité de ton exemple.

  3. #3
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    Bonjour et merci de ta réponse.

    En base, j'ai bien la table Niveau. Et tout se passe bien vu que j'arrive à insérer des valeurs du style : 1 - Chef de Projet

    Mais quand je veux insérer la ressource "Durant" qui est chez de projet" je vais un Ressource.save(objetRessource) et là, ça ne fonctionne pas car en base, il s'attend à : identifiant, nom, prénom, matricule, mdp, id_niveau(qui est clé étrangère) Alors que moi je lui passe en paramètre un objet ressource qui comprend un objet niveau !!!!

    Je ne sais pas si j'arrive bien à me faire comprendre.

    Merci de vos réponses.

  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
    Est-ce que ça ne viendrait pas de ton mapping ?

    Pour les relations 1-1, j'utilise plutôt, un many-to-one avec unique = true
    plutôt qu'un one-to-one.

  5. #5
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    un many - to - one fait la même chose qu'un one - to - one ?

    En plus, je ne trouve pas beaucoup de doc sur le one to one. Mais qu'est ce qu'il faut que je mette en plus dans le fichier de mapping ?

    Par contre, je ne comprends pas trop pourquoi ça pourrait mieux fonctionner ?

  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

  7. #7
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    Par contre, je ne comprends pas tout.

    Le one - to -one on le fait sur quel classe ?

    Dans mon exemple, j'ai une classe ressource qui possède un attribut : leNiveau qui est un lien un objet de la table niveau.

    Donc moi je mappe la classe Ressource mais je ne sais pas ?

  8. #8
    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
    Prends l'exemple que je t'ai filé avec le many-to-one.
    Ca devrait correspondre à ton cas.

  9. #9
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    Justement j'ai dû mal à comprendre car pour moi le one-to-one se fait que sur une classe et j'ai l'impression que dans ton exemple, on fait quelque chose sur les 2 tables.

    Si tu pouvais pour m'expliquer prendre mon exemple. Car moi quand je rajoute une ressource, je ne veux pas rajouter un niveau mais simplement insérer l'identifiant du niveau auquel appartient la ressource.

    En tout cas, merci pour tes réponses.

  10. #10
    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
    J'ai bien compris ton problème.
    Et ça marche très bien dans ce cas là.

    Il te suffira de faire: res.setLeniveau(tonObjetNiveauChargé);

  11. #11
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    Oui, je suis d'accord avec toi, j'ai bien un objet qui comprend toutes les infos sur la Ressource et un objet niveau comprenant l'identifiant et le libellé.

    Tout ceci est dans un objet. Mais pour faire l'insertion en base tu fais comment ?

    j'ai essayé ça : session.save(objetResource);

    Mais forcément ça ne fonctionne mais, je ne vois pas comment je peux faire pour juste lui donner l'identifiant du niveau pour qu'il puisse l'insérer.

  12. #12
    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
    Niveau niv = session.load(Niveau.class, id);

    Ressource res = new Ressource();
    res.setMatricule("0001");
    res.setNom("martin");
    res.setPrenom("maurice");
    res.setMotDePasse("z5q6z");
    res.setLeniveau(niv);
    session.save(res);

    Voilà en gros, ce que j'écrirais.

  13. #13
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    ca ne fonctionne pas.

    Voilà ce que je faisait :

    Niveau niv=new Niveau();
    niv.setCodeNiveau(new Integer(6));
    session.refresh(niv);


    res.setMatricule("?");
    res.setNom("?");
    res.setPrenom("?");
    res.setMotDePasse("?");
    res.setLeniveau(niv);
    session.save(res);

    Et ça et bien ça ne fonctionne pas et voici l'erreur ... Je comprends mais je ne sais pas comment résoudre le souci.

    08:49:50,492 DEBUG SQL:346 - insert into planning.ressource (Matricule, NomR, PrenomR, MDPR, ID_RES) values (?, ?, ?, ?, ?)
    Hibernate: insert into planning.ressource (Matricule, NomR, PrenomR, MDPR, ID_RES) values (?, ?, ?, ?, ?)
    08:49:50,523 WARN JDBCExceptionReporter:71 - SQL Error: 1452, SQLState: 23000
    08:49:50,523 ERROR JDBCExceptionReporter:72 - Cannot add or update a child row: a foreign key constraint fails (`planning/ressource`, CONSTRAINT `FK_Ressource_Niveau` FOREIGN KEY (`ID_NIVEAU`) REFERENCES `niveau` (`CodeNiv`))
    08:49:50,539 ERROR AbstractFlushingEventListener:300 - Could not synchronize database state with session
    org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:202)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at com.simecom.planning.test.Test.main(Test.java:70)
    Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`planning/ressource`, CONSTRAINT `FK_Ressource_Niveau` FOREIGN KEY (`ID_NIVEAU`) REFERENCES `niveau` (`CodeNiv`))
    at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:665)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
    ... 8 more

  14. #14
    BsT
    BsT est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 72
    Par défaut
    Hello,

    Si tu as dans ta table Niveau une ligne avec ("6", "libelle"), il faut que tu écrives :

    Niveau niv = (Niveau) session.load(Niveau.class, 6); (comme le precise fr1man)

    Sinon si tu n'as pas cette ligne

    il faut que tu écrives

    Niveau niv=new Niveau();
    niv.setLibelle("toto");
    session.save(niv);

    Je te recommande d'éviter de manipuler les id (sauf pour les session.get, session.load bien évidement)

    Edit : Je viens de relire le thread il faut tu utilises comme générateur d'id pour Niveau "assigned" puis session.save(niv). Mais ce n'est pas correct. Un id ne doit pas contenir de données dependante de ton application

  15. #15
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    Ok mais quand tu fais : session.save(niv); ca va enregistrer en base et c'est pas ce que je veux. Je veux uniquement enregistrer une ressource.

    Je comprends bien qu'il ne faut pas trop utiliser les ID mais, je suis bien obligé de le faire pour pouvoir insérer mon niveau. Sinon la solution serait d'enlever la clé étrangère et d'insérer en deux fois. La première fois on insère la ressource et la seconde on insére l'identifiant du niveau. Mais c'est quand même dommage de ne pas utiliser les clé étrangères.

    tu mets :

    Edit : Je viens de relire le thread il faut tu utilises comme générateur d'id pour Niveau "assigned" puis session.save(niv). Mais ce n'est pas correct. Un id ne doit pas contenir de données dependante de ton application
    Je ne comprends pas trop. Niveau = "assigned" ça fait quoi ?

    Et je ne comprends pas ta dernière phrase.

    Merci de m'éclairer sur le sujet.

  16. #16
    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
    Alors utilise un load et non pas un save sur ton niveau.

    Qu'est ce qui ne marche pas dans ce que je t'ai dit de faire ?

  17. #17
    BsT
    BsT est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 72
    Par défaut
    Alors pour le assigned

    <class name="Niveau" table="niveau">
    <id name="codeNiveau" column="CodeNiv">
    <generator class="assigned"/>
    </id>
    <property name="libelle" column="LibelleNiv" />
    </class>

    Voir : http://www.hibernate.org/hib_docs/v3...on-id-assigned

    Pour la dernière phrase :

    Par exemple :

    Aujourd'hui tu as dans niveau (6, "Chef de Projet") si tu décides plus tard que le code niveau pour un chef de projet c'est 220. Tu peux alors imaginer les corrections à apporter dans la base.

    Le mieux c'est d'avoir :

    <class name="Niveau" table="niveau">
    <id name="niveauId" column="NIVEAU_ID">
    <generator class="increment"/>
    </id>
    <property name="codeNiveau" column="code_niveau"/>
    <property name="libelle" column="LibelleNiv" />
    </class>

    Mais bon il s'agit plus de conception que de pb avec hibernate la

  18. #18
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    Le problème pour moi ne vient pas de Niveau car tout fonctionne pour Niveau, j'arrive à l'insérer, visualiser, je n'ai pas de souci avec.

    Par contre, mon souci est sur Ressource.

    Ok pour assigned.

  19. #19
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 60
    Par défaut
    Pas de nouvelles !!!!

  20. #20
    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
    Je t'ai proposé un mapping et du code. Je ne peux rien de plus.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Appel Java puis Hibernate depuis JSP
    Par zezitinho dans le forum Servlets/JSP
    Réponses: 50
    Dernier message: 15/12/2008, 09h23
  2. Requête SQL de base sous java avec Hibernate
    Par ritchie23 dans le forum JDBC
    Réponses: 0
    Dernier message: 29/10/2008, 09h54
  3. Chiffrage application web java jsp hibernate
    Par padraig29 dans le forum Devis
    Réponses: 1
    Dernier message: 20/11/2006, 15h07
  4. Requête ORACLE en java avec hibernate
    Par solange44 dans le forum Hibernate
    Réponses: 2
    Dernier message: 03/10/2006, 08h33

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