Bonjour,
je fais la modification un objet,alors toue se passe bien,sauf pour le champs de type Foreing key,qui garde l'ancienne valeur,je sais pas est ce que d'abord c'est possible de faire la modification d'un champs FK ?
Version imprimable
Bonjour,
je fais la modification un objet,alors toue se passe bien,sauf pour le champs de type Foreing key,qui garde l'ancienne valeur,je sais pas est ce que d'abord c'est possible de faire la modification d'un champs FK ?
Heuuuu, vous pouvez répéter la question? Rien compris!
Ma question est la suivante: je veux faire la modification d'un enregistrement,alors lorsque j'appelle ma fct de modification,tous les champs de ma table sont modifiés apart le champs qui est une clé étrangère ds la table,je sais pas est ce que d'abord c'est possible de faire la modification d'un champs qui est une clé étrangère ?
avec hibernate les clé étrangères sont gérées par les relation entre les objet.
Exemple, si un table "client" référence un table "vendeur" (un vendeur s'occupe de son client), et que tu veux changer la clé étrangère client -> vendeur, tu dois, avec l'objet client faire:
Evidement, il ne faut pas oublier de référencer ce mapping client -> vendeur sous forme d'une relation many-to-one dans le mapping hibernate.Code:client.setVendeur(vendeur)
C'est ce que j'ai fait,mais j'ai comme erreur :
en fait lorsque je valide le formulaire de modification j'ai l'exception précédente,mais si je valide le formulaire une 2 fois la modification marche trés bienCode:
1
2 identifier of an instance of Mapping.MAtable was altered from "ancienne_valeur" to "nouvelle_valeur"
En fait c'est une clé étrangère ,mais c'est aussi une clé primaire d'une autre table mais qui a migré vers la table ou je fé la modification,sinon comment tu pe expliquer le fait que la modification passe la 2 fois
sans voir le code, difficile, mais si tu change le champ marqué dans ton mapping hibernate comme "primary key", çà ne passera pas.
voilà le code :
alors j'ai deux table utilisteur et centre,la table utilisateur a comme clé primaire login et clé etrangere codecentre,qui est une clé primaire dans la tble centre
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 org.hibernate.Session session = HibernateUtil.currentSession(); org.hibernate.Transaction tx = session.beginTransaction(); org.hibernate.Query query = session.createQuery("from Utilisateur as user where user.login='"+pc.getLogin()+"'"); Utilisateur user= (Utilisateur)query.list().get(0); user.setEmail(pc.getEmail()); user.setNom(pc.getNom()); user.setPassword(pc.getPassword()); user.setPrenom(pc.getPrenom()); user.setProfil(pc.getProfil()); user.setQuestionSecrete(pc.getQuestionSecrete()); user.setReponse(pc.getReponse()); user.setTelephone(pc.getTelephone()); org.hibernate.Query query1 = session.createQuery("from Centre as centre where centre.code='"+pc.getCentre().getCode()+"'"); centre = (Centre)query1.list().get(0); user.setCentre(centre); session.save(user) ; tx.commit();
je rapelle que la modification de tous les champs passe bien sauf,pour la clé etrangere
rien de mauvais a priori dans le code. On pourrait voir à quoi correspond "Mapping.MAtable"? Parce que je ne vois pas cette classe utilisée. Es-tu sur de ne pas avoir fait d'autre modifications d'objets hibernate avant de faire tes select? On pourrais voir à quelle ligne exactement a lieu l'exception?
En fait MAtable c'est centre,donc l'erreur c'est :
tout à l'heure j'ai utilisé "Matable" que pour donner un exempleCode:
1
2 identifier of an instance of Mapping.Centre was altered from "ancienne_valeur" to "nouvelle_valeur"
la fichier de mapping de la table utilisateur est :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class dynamic-insert="false" dynamic-update="false" mutable="true" name="Mapping.Utilisateur" optimistic-lock="version" polymorphism="implicit" select-before-update="false" table="utilisateur"> <id column="login" name="login" type="string"> <generator class="assigned"/> </id> <property column="password" name="password" not-null="true" type="string"/> <property column="nom" name="nom" not-null="true" type="string"/> <property column="prenom" name="prenom" not-null="true" type="string"/> <property column="telephone" name="Telephone" not-null="true" type="string"/> <property column="email" name="email" not-null="true" type="string"/> <property column="question_secrete" name="questionSecrete" not-null="true" type="string"/> <property column="reponse" name="reponse" not-null="true" type="string"/> <property column="profil" name="profil" not-null="true" type="string"/> <many-to-one class="Mapping.Centre" name="centre"> <column length="10" name="code_centre_"/> </many-to-one> </class> </hibernate-mapping>
pourrait-on voir le mapping de centre ainsi que l'erreur exacte avec son stacktrace?
Pour le mapping de la classe centre :
pour l'erreur :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 <class dynamic-insert="false" dynamic-update="false" mutable="true" name="Mapping.Centre" optimistic-lock="version" polymorphism="implicit" select-before-update="false" table="centre"> <id column="code" name="code" type="string"> <generator class="assigned"/> </id> <property column="nom" name="nom" type="string"/> <property column="telephone" name="telephone" type="string"/> <property column="adresse" name="adresse" type="string"/> <property column="code_postale" name="codePostale" type="integer"/> <property column="fax" name="fax" type="string"/> <property column="pays" name="pays" not-null="true" type="string"/> <many-to-one class="Mapping.Ville" column="code_ville" name="ville"/> </class>
org.HibernateException
identifier of an instance of Mapping.Centre was altered from "ancienne_valeur" to "nouvelle_valeur"
Ok, on peut voir la ligne exacte de l'erreur. A quoi crrespondent "ancienne_valeur" et "nouvelle_valeur". Es-tu sur de ne pas changer Mapping.Centre.code depuis "ancienne_valeur" vers nouvelle_valeur. J'ai l'impression que tu utilise JSF en front-end. Ca pourrais arriver si, par erreur, t'as mappé une valeur du formulaire sur cette clé primaire et que tu la change dans le formulaire.
En fait,je veux par exemple modifier le code du centre d'un utilisateur de ancienne valeur vers nouvelle valeur.
Le problème c'est que tu change le champ "code" de l'objet Centre, via ton interface, plutot que de choisir un autre objet Centre. Comme le champs code est une clé primaire de Centre, le changer dans Centre pose ton problème. Il faut revoir la manière dont ton utilisateur choisir le Centre. Soit tu pointe ce champ texte vers un bean qui n'est pas Centre.code (et donc ne clache pas avec hibernate), soit tu fais un dropdown dans lequel on choisi un objet Centre. Dans tous les cas, ne fait pas pointer un champ éditable vers Centre.code !
En fait,je récupère la nouvelle valeur du champs code d'une liste déroulante que j'ai déjà rempli par les codes des centres disponibles,c j'ai bien compris votre réponse,c pas possible de modifier le clef étrangère directement ??
Tu confond la clé étrangère de Mapping.Utilisateur et la clé primaire de Mapping.Centre.
Je gage que tu as créé ton SelectOneMenu d'une manière similaire à la suivante:
Si je lit bien tes post, "utilisateur" dans mon cas serait un bean différent de l'objet hibernate (ce qui est bien, une isolation qui sépare la partie interface de la partie base de donnée). Mais ton objet utilisateur.centre est probablement directement l'objet hibernate de type Mapping.centre. Résultat, quand tu choisi qqch dans la liste, JSF va aller changer centre.code, centre étant un objet hibernate, tu viens de modifier la clé primaire de l'objet hibernate. Ce qui va méchament clacher lors du flush.Code:
1
2
3
4<h:selectOneMenu value="#{utilisateur.centre.code}"> <!-- liste des codes --> </h:selectOneMenu>
Une solution serait de convertir en quelque chose comme çà:
Note que çà m'a l'air plus d'un problème au niveau design jsf (choix de ce que tu modifie en jsf) qu'un problème avec le code de ton action (qui lui a l'air correct).Code:
1
2
3<h:selectOneMenu value="#{utilisateur.centre}"> <!-- liste de centre --> </h:selectOneMenu>
Si t'as besoin de plus d'info, poste
- le bout de code jsf concerné
- tes beans jsf
Merci pour votre réponse,
vus avez raison le selectOneMenu est :
alors que dans mon bean voilà la partie d'insertion de du code ds la table utilisateur :Code:
1
2
3
4 <td> <h:selectOneMenu id="Menu1" value="#{user.pc.centre.code}" style="width:100%"> <f:selectItems value="#{centre.uneliste}" /> </h:selectOneMenu></td>
Code:
1
2
3
4 org.hibernate.Query query1 = session.createQuery("from Centre as centre where centre.code='"+pc.getCentre().getCode()+"'"); centre = (Centre)query1.list().get(0); user.setCentre(centre);
avec Centre c'est une instanciation de la classe Mapping.Centre
La partie dans ton action est correcte. Par contre, à quelle classe correspond #{user.pc.centre}? Si c'est un bean hibernate, il ne faut absolument pas mapper sa propriété code sur la value d'un composant jsf.