Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1481 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  nhibernate : one-to-many

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

nhibernate : one-to-many

n°1771325
twisted
Ahhhhhhhh !
Posté le 08-08-2008 à 17:00:36  profilanswer
 

salut,  
 
J'ai un soucis avec nhibernate et le mapping many to one.
 

Citation :

"Le nom de colonne 'IDSOCIETE' apparaît plusieurs fois dans la liste des colonnes de résultat"


 
j'ai une table news et une table société.
dans la table news, j'ai une clé étrangère vers société.
 
avec cette ligne cela fonctionne :  
<many-to-one name="Societe" class="Webmain.Common.Modules.Societe.Societe, Webmain" column="IDSOCIETE" cascade="all" />
 
je récupère bien les éléments de la société.
cependant, cela ne fonctionne qu'en lecture. si je jeux insérer dans la base cela ne fonctionne plus étant donné que j'ai 2x la colonne IDSOCIETE mappée.
<property name="IdSociete" column="IDSOCIETE" not-null="true" type="System.Int32" access="property" />
 
or, j'ai besoin de l'idSociete pour faire mes update.  
 
comment faire ?
 
merci d'avance


Message édité par twisted le 08-08-2008 à 17:00:47
mood
Publicité
Posté le 08-08-2008 à 17:00:36  profilanswer
 

n°1772202
twisted
Ahhhhhhhh !
Posté le 11-08-2008 à 21:56:45  profilanswer
 

aidez-moi. je débute avec nhibernate et je ne vois vraiment pas comment faire..
de plus, je dois rendre le projet dans peu de temps  :sweat:  
 
s'il vous plait

n°1772205
h4rold
Posté le 11-08-2008 à 22:03:43  profilanswer
 

Tu peux mettre tes fichiers xml en entier parceque la j'ai du mal a comprendre ce que tu essaie de faire.

n°1772237
twisted
Ahhhhhhhh !
Posté le 11-08-2008 à 22:40:17  profilanswer
 

ok. alors voici mes deux fichiers xml :
 

Code :
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" default-access="nosetter.camelcase">
  3.     <class name="Webmain.Common.Modules.Utilisateur.Utilisateur, Webmain" table="UTILISATEURS">
  4.         <id name="IdUtilisateur" column="IDUTILISATEUR" type="System.Int32" access="property">
  5.             <generator class="identity"/>
  6.         </id>
  7.         <property name="IdSociete" column="IDSOCIETE" not-null="true" type="System.Int32" access="property" />
  8.         <property name="Nom" column="NOM" not-null="true" type="System.String" access="property" />
  9.         <property name="Prenom" column="PRENOM" not-null="true" type="System.String" access="property" />
  10.         <property name="Login" column="LOGIN" not-null="true" type="System.String" access="property" />
  11.         <property name="Mdp" column="MDP" not-null="true" type="System.String" access="property" />
  12.         <property name="Email" column="EMAIL" not-null="true" type="System.String" access="property" /> 
  13.         <many-to-one name="Societe" class="Webmain.Common.Modules.Societe.Societe, Webmain" column="IDSOCIETE" cascade="all" />
  14.     </class>
  15. </hibernate-mapping>


 

Code :
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" default-access="nosetter.camelcase">
  3.     <class name="Webmain.Common.Modules.Societe.Societe, Webmain" table="SOCIETES">
  4.         <id name="IdSociete" column="IDSOCIETE" type="System.Int32" access="property">
  5.             <generator class="identity"/>
  6.         </id>
  7.         <property name="RaisonSociale" column="RAISONSOCIALE" not-null="true" type="System.String" access="property" />
  8.     </class>
  9. </hibernate-mapping>


 
cela fonctionne bien si je veux récupérer une valeur.
par exemple si la variable "user" est de type Utilisateur, je peux faire :
user.Login
user.Societe.RaisonSociale
...
 
en revanche quand je veux ajouter un enregistrement dans la base avec Save(), cela ne fonctionne plus.
"Le nom de colonne 'IDSOCIETE' apparaît plusieurs fois dans la liste des colonnes de résultat".
J'imagine que nhibernate ne peut pas mapper le même champ pour 2 propriétés.
 
dans ce cas, comment utiliser mon IDSOCIETE pour pouvoir le mettre à jour ?
 
je te remercie d'avance de ton aide ;)


Message édité par twisted le 11-08-2008 à 22:41:23
n°1772311
h4rold
Posté le 12-08-2008 à 09:59:21  profilanswer
 

Je n'ai fait de l'hibernate qu'en java donc je ne peux que t'aider sur le fichier hibernate mais il faudra que tu mette aussi ton code à jour en conséquence.
 
En fait tu demande a hibernate de créer 2 fois la même colonne ce qu'il ne peux pas faire.
Si j'ai bien compris tu veux qu'une société peux avoir plusieurs utilisateurs mais qu'un utilisateur ne peut être associé à qu'une seule société. (d'où le one-to-many / many-to-one)
 
Il te faut donc qu'une seule association one-to-many dans la classe Utilisateur

Code :
  1. <many-to-one name="Societe" class="Webmain.Common.Modules.Societe.Societe, Webmain" column="IDSOCIETE" cascade="all" />


me semble bien
 
Par contre il faut que tu fasse l'association dans l'autre sens dans la classe Societe avec quelque chose qui doit ressembler a cela : (j'utilise set qui correspond au set de java qui est une simple collection, il faut que tu trouve l'équivalent en C#)

Code :
  1. <set name="utilisateurs" inverse="true">
  2.    <key column="IDSOCIETE" />
  3.    <one-to-many class="Webmain.Common.Modules.Utilisateur.Utilisateur, Webmain" />
  4. </set>


 
 
Je n'ai pas très bien compris pourquoi tu veux deux élements ayant le meme nom dans la même classe mais ce n'est pas possible. (le xml d'hinbernate correspond bien à un objet et un objet ne peux avoir plusieurs membres ayant le même nom)


Message édité par h4rold le 12-08-2008 à 10:03:02
n°1772320
twisted
Ahhhhhhhh !
Posté le 12-08-2008 à 10:07:16  profilanswer
 

ok. donc, je récapitule, (dis moi si ce que j'écris est faux) :
 
avec la property Societe dans Utilisateur : je récupère la Société associé à l'utilisateur
avec la property utilisateurs dans Societe : je récupère la liste des utilisateurs de la société
 
tout cela fonctionne  :)  :)  
en revanche pour mettre à jour, je ne peut plus utiliser l'id de la clé étrangère.
j'ai trouvé une solution il y a une heure, ça fonctionne mais ce n'est peut être pas la bonne façon de faire.
 
j'envoie directement l'objet dans la property.
 
je fait :  
 
Utilisateur u = new Utilisateur();
u.Nom = "toto"
u.Societe = maSociete; // maSociete est de type Societe
 
c'ets correct ?

n°1772408
h4rold
Posté le 12-08-2008 à 12:07:50  profilanswer
 

twisted a écrit :

ok. donc, je récapitule, (dis moi si ce que j'écris est faux) :
 
avec la property Societe dans Utilisateur : je récupère la Société associé à l'utilisateur
avec la property utilisateurs dans Societe : je récupère la liste des utilisateurs de la société
 
tout cela fonctionne  :)  :)  
en revanche pour mettre à jour, je ne peut plus utiliser l'id de la clé étrangère.
j'ai trouvé une solution il y a une heure, ça fonctionne mais ce n'est peut être pas la bonne façon de faire.
 
j'envoie directement l'objet dans la property.
 
je fait :  
 
Utilisateur u = new Utilisateur();
u.Nom = "toto"
u.Societe = maSociete; // maSociete est de type Societe
 
c'ets correct ?


 
C'est exactement la facon de faire avec Hibernate. Tu as besoin des clefs primaire et étrangeres pour que hibernate puisse les manager dans la base de donnée mais le but est de ne jamais les utiliser dans ton code. (sauf a la rigueur si tu fait du web pour se passer un id entre le client et le serveur / tu as aussi besoin de créer les getter/setters pour que Hibernate puisse les utiliser)
Il faut cependant que maSociete existe et soit déja enregistré dans la base (un Save() )
 
Le but d'hibernate est vraiment de ne plus a se soucier de la base de donnée et de raisonner en objet (en sachant qu'en plus derriere tu n'es pas obligé de mettre une base, tu peux mettre du xml par exemple)


Message édité par h4rold le 12-08-2008 à 12:09:58
n°1772462
twisted
Ahhhhhhhh !
Posté le 12-08-2008 à 13:54:11  profilanswer
 

ok. maintenant tout mon mapping fonctionne.
 
merci beaucoup pour tes explications ;)

n°1772551
h4rold
Posté le 12-08-2008 à 15:43:20  profilanswer
 

No prob. Si tu as d'autre problème, je me suis suffisement cassé les dents sur Hibernate pour pouvoir éventuellement te répondre :)

n°1772579
twisted
Ahhhhhhhh !
Posté le 12-08-2008 à 16:45:03  profilanswer
 

h4rold a écrit :

No prob. Si tu as d'autre problème, je me suis suffisement cassé les dents sur Hibernate pour pouvoir éventuellement te répondre :)


 
merci :) ça m'arrange, j'ai un autre problème.
 

Code :
  1. deleted object would be re-saved by cascade (remove deleted object from associations): 1, of class: Webmain.Common.Modules.Societe.Societe


 
d'après ce que j'ai lu sur le net, ce problème apparait lorsqu'on ajoute notamment des relations many-to-one.
 
ma fonction de suppression :
 

Code :
  1. public void deleteOne(object item)
  2.         {
  3.             ITransaction transaction = null;
  4.             try
  5.             {
  6.                 transaction = session.BeginTransaction();
  7.                 session.Delete(item);
  8.                 transaction.Commit();
  9.             }
  10.             catch
  11.             {
  12.                 if (transaction != null)
  13.                     transaction.Rollback();
  14.                 throw;
  15.             }
  16.         }


 
si tu as une idée d'où pourrait venir ce problème.
 
merci d'avance

mood
Publicité
Posté le 12-08-2008 à 16:45:03  profilanswer
 

n°1772584
h4rold
Posté le 12-08-2008 à 16:55:28  profilanswer
 

twisted a écrit :


 
merci :) ça m'arrange, j'ai un autre problème.
 

Code :
  1. deleted object would be re-saved by cascade (remove deleted object from associations): 1, of class: Webmain.Common.Modules.Societe.Societe


 
d'après ce que j'ai lu sur le net, ce problème apparait lorsqu'on ajoute notamment des relations many-to-one.
 
ma fonction de suppression :
 

Code :
  1. public void deleteOne(object item)
  2.         {
  3.             ITransaction transaction = null;
  4.             try
  5.             {
  6.                 transaction = session.BeginTransaction();
  7.                 session.Delete(item);
  8.                 transaction.Commit();
  9.             }
  10.             catch
  11.             {
  12.                 if (transaction != null)
  13.                     transaction.Rollback();
  14.                 throw;
  15.             }
  16.         }


 
si tu as une idée d'où pourrait venir ce problème.
 
merci d'avance


 
Je pense que le problème vient du fait que dans un one-to-many, 1 instance d'une classe (one) est lié à plusieurs instances d'une autre classe (many). Si tu supprime une instance du one, alors les many seront associés à une instance qui n'existe plus d'où le fait qu'il ne puisse pas la supprimer.
 
En gros tu peux supprimer un utilisateur sans problème (hibernate enlevera l'instance Utilisateur et la supprimera de la collection membre de la classe Societe) mais tu ne peux pas supprimer une société car des utilisateurs existent et sont liés à cette société. (il faut a ce moment la les licensier ;))
 
Je ne suis plus sur mais si tu met un not-null="false" alors l'association ne seras plus obligatoire des utilisateurs a la société. ( un utilisateur pourra ne pas avoir de société)

n°1772632
twisted
Ahhhhhhhh !
Posté le 12-08-2008 à 18:34:39  profilanswer
 

Citation :

Je ne suis plus sur mais si tu met un not-null="false" alors l'association ne seras plus obligatoire des utilisateurs a la société. ( un utilisateur pourra ne pas avoir de société)


 
Un utilisateur doit avoir une société. mon champ idSociete dans la table utilisateur est en not null. avec une contrainte foreign key vers la clé primaire de la table société.
c'est donc normal que j'ai une exception si je veux supprimer une société utilisée par un utilisateur.
 
en revanche, je pense que ce n'est pas normal d'avoir une erreur pour supprimer un utilisateur (personne ne référence sa clé primaire).
 
tu n'as pas d'autres idées?

n°1772674
h4rold
Posté le 12-08-2008 à 21:17:50  profilanswer
 

twisted a écrit :

Citation :

Je ne suis plus sur mais si tu met un not-null="false" alors l'association ne seras plus obligatoire des utilisateurs a la société. ( un utilisateur pourra ne pas avoir de société)


 
Un utilisateur doit avoir une société. mon champ idSociete dans la table utilisateur est en not null. avec une contrainte foreign key vers la clé primaire de la table société.
c'est donc normal que j'ai une exception si je veux supprimer une société utilisée par un utilisateur.
 
en revanche, je pense que ce n'est pas normal d'avoir une erreur pour supprimer un utilisateur (personne ne référence sa clé primaire).
 
tu n'as pas d'autres idées?


 
Heu dans la logique si tu veux supprimer un utilisateur tu supprime la référence dans la liste de la société "possédant" cette utilisateur. Ensuite tu commit et ca devrait passer :)

n°1772956
twisted
Ahhhhhhhh !
Posté le 13-08-2008 à 17:28:19  profilanswer
 

Citation :

tu supprime la référence dans la liste de la société "possédant" cette utilisateur


 
je ne comprend ce que tu veux dire par supprimer la référence.
j'ai beau cherché dsl, je vois pas.
tu peux mettre du code java sans problème, je traduirais en c#.

n°1772976
h4rold
Posté le 13-08-2008 à 18:06:00  profilanswer
 

Utilisateur u;
...
u.getSociete().getListUtilisateurs.remove(u);
Tu choppe la société correspondant à l'utilisateurs et tu supprime l'utilisateurs de la liste de ses utilisatreurs.

n°1773090
twisted
Ahhhhhhhh !
Posté le 13-08-2008 à 23:51:24  profilanswer
 

j'ai essayé ce que tu dis. en c#, cela donne :
 

Code :
  1. u.Societe.ListeUtilisateurs.Remove(u);


 
mais aucune différence. j'ai toujours la même exception  :(  
 
dans la doc, je ne voit rien à ce sujet. je ne sais plus quoi faire.

n°1773618
twisted
Ahhhhhhhh !
Posté le 15-08-2008 à 16:34:10  profilanswer
 

j'ai résolution mon problème en mettant l'attribut cascade à none sur les many-to-one.
 
en espérant qu'il n'y aura pas d'effets de bord...


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  nhibernate : one-to-many

 

Sujets relatifs
Configuration Spring.net et NHibernateMapping Nhibernate
Mapping NHibernate probleme <composite-id>Génération de Mapping O/R NHibernate avec MyGeneration
NHibernate et MySql 5.0Nhibernate
Nhibernate pb de sessionNHibernate SQL natif
C++ ==> \stdlib.h too many arguments to functionNHIBERNATE "outer or full join must be followed by path expression"
Plus de sujets relatifs à : nhibernate : one-to-many


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR