2009-12-24 7 views
1

Je suis nouveau à NHibernate et l'ai trouvé extrêmement intéressant. J'ai essayé de persister des objets dans une table de mappage (la table qui casse de nombreuses relations dans la conception de base de données relationnelle) mais qui n'a pas été capable de le faire jusqu'à présent. Je suis capable de récupérer des données de la table de mappage en utilisant mon mappage hibernate actuel, cependant.Aide avec NHibernate Insérer/Mettre à jour

Voici ce que ma base de données ressemble à:

Groupes (groupId, groupName) rapports (reportId, REPORTNAME) GroupReports (groupeId, reportId)

relations très typiques et simples en termes de modélisation des données .

Je sais que cette question a été posée plusieurs fois et j'en ai lu beaucoup. Croyez-moi, j'ai vraiment fait.

Voici ma correspondance pour la classe des entités du Groupe:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer"> 
    <class name="DataTransfer.Group, DataTransfer" table="GROUPS"> 
    <id name="GroupId"> 
     <column name="groupId" sql-type="int" not-null="true"/> 
     <generator class="native"/> 
    </id> 
    <property name="GroupName" column="groupName" type ="string" length="150" not-null="true"/>  
    <bag name="Reports" cascade="none" inverse="true"> 
     <key column="groupId"/> 
     <many-to-many column="reportId" class="DataTransfer.Report, DataTransfer"/>  
    </bag> 
    </class> 
</hibernate-mapping> 

Et ma correspondance pour la classe entité rapport aime ci-dessous:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer"> 
    <class name="DataTransfer.Report, DataTransfer" table="REPORTS" > 
    <id name="ReportId" column="reportId" type="int" unsaved-value="0"> 
     <generator class="native"/> 
    </id>   
    <property name = "ReportName" column="reportName" type="string" length="250" not-null="true"/> 
    <bag name="MappedGroups" table="GroupReports" cascade="all" inverse="false" lazy="true"> 
     <key column="reportId"/> 
     <many-to-many class="DataTransfer.Group, DataTransfer" column="groupId" />   
    </bag>  
    </class> 
</hibernate-mapping> 

Selon ce que je lis, ces applications doivent permettre moi à la fois récupérer et conserver les données de mappage de la table des associés GroupReports. Mon code de test unitaire ne révèle que l'instruction SQL sélectionnée, pas d'insertions dans la table de mappage.

Étant donné mes mappages, que devrait-on faire pour conserver les données de mappage?

Répondre

1

En supposant que vous configuriez correctement votre sessionfactory/session (puisque vous obtenez des instructions SELECT), je parierais que vous n'utilisez pas de transactions ou de diffusion de votre session.

La méthode recommandée pour mettre à jour les données dans NHibernate est de toujours utiliser une transaction. Quelque chose comme ceci:

using(var session = sessionFactory.OpenSession()) 
using(var tx = session.BeginTransaction()) 
{ 
    var group = new Group {GroupName="Programmers Anonymous"}; 
    session.Save(group); 
    tx.Commit(); 
} 

Cela devrait vous aider à démarrer.

--UPDATE--

après avoir lu votre autre question, il semble que vous voulez que ce code ...

session.Save(report); 

pour automatiquement les groupes persistent aussi bien. Mais dans votre mappage, vous avez défini la collection de groupes en tant que cascade="none". Changez cela en cascade="save-update" et ça va le réparer.

Espérons que cela répond à votre question.

+0

(notez l'OP a ajouté une mise à jour re cette réponse) –

0

Merci Ben, pour votre réponse. Je n'ai pas pu trouver mon poste jusqu'à aujourd'hui. :-).

En fait, j'ai utilisé la transaction dans mon code. Voici le code de ma méthode Add:

public int Add(Report obj) 
     { 
      //set the flush mode to Never so that session.save() does not cause a flush until the commit() 
      //on transaction is called 
      _session.FlushMode = FlushMode.Never; 
      using (ITransaction tx = _session.BeginTransaction()) 
      { 
       try 
       { 
        int newId = (int)_session.Save(obj); 
        tx.Commit();//this will cause the a flush of the session 
        return newId; 
       } 
       catch (HibernateException) 
       { 
        tx.Rollback(); 
        throw; 
       } 
      } 
     } 

Je peux enregistrer l'objet parent avec ce code. Dans mon cas, je suis capable de conserver l'objet Report dans la base de données.Voici mon code de test unitaire pour sauver le parent et les objets enfants en utilisant les nombreux à plusieurs cartographie des relations:

const string reportCd = "TE"; 
const string reportName = "Test Report 6"; 
Report report = new Report; 
report.ReportCd = reportCd; 
report.ReportName = reportName; 
report.IsPublicFlag = 0; 

IList<Group> groups = new List<Group>(); 

Group group = new Group(); 

group.GroupId = 2; 
groups.Add(group); 

report.Groups = Groups; 
_provider.Add(report); 

L'objet _provider est mon objet Dao qui a la méthode Add mentionnée ci-dessus.

De plus, étant donné que le rapport et le groupe sont des objets plusieurs-à-plusieurs, ils contiennent un IList l'un de l'autre. Les groupes de l'objet Report est un IList de l'objet Group et l'objet Group a un rapport IList.

Encore une fois, merci pour votre aide.

John

+0

Je mis à jour ma réponse pour répondre, espérons mieux le problème. –

Questions connexes