0

First, I'm using NHibernate 3.2 and FluentNHibernate 1.3. I have 3 clasess:

public class ClassA
{
    public virtual Int32 Id{ get; }
    ....
    public ICollection<ClassB> ClassesB { get; }
    public ICollection<ClassC> ClassesC { get; }
}

public class ClassB
{
    public virtual Int32 Id{ get; }
    ....
    public ICollection<ClassA> ClassesA { get; }
    public ICollection<ClassC> ClassesC { get; }
}

public class ClassC
{
    public virtual Int32 Id{ get; }
    ....
    public ICollection<ClassA> ClassesA { get; }
    public ICollection<ClassB> ClassesB { get; }
}

I mapped them with this code:

public class ClassAMap : ClassMap<ClassA>
{
    public ClassAMap()
        : base()
    {
        Id(m => m.Id);
        ....

        HasManyToMany<ClassB>(m => m.ClassesB).Cascade.SaveUpdate().AsSet().ReadOnlyAccess();
        HasManyToMany<ClassC>(m => m.ClassesC).Cascade.SaveUpdate().AsSet().ReadOnlyAccess();
    }
}

public class ClassBMap : ClassMap<ClassB>
{
    public ClassBMap()
        : base()
    {
        Id(m => m.Id);
        ....

        HasManyToMany<ClassA>(m => m.ClassesA).Cascade.SaveUpdate().AsSet().ReadOnlyAccess();
        HasManyToMany<ClassC>(m => m.ClassesC).Cascade.SaveUpdate().AsSet().ReadOnlyAccess();
    }
}

public class ClassCMap : ClassMap<ClassC>
{
    public ClassCMap()
        : base()
    {
        Id(m => m.Id);
        ....

        HasManyToMany<ClassA>(m => m.ClassesA).Cascade.SaveUpdate().AsSet().ReadOnlyAccess();
        HasManyToMany<ClassB>(m => m.ClassesB).Cascade.SaveUpdate().AsSet().ReadOnlyAccess();
    }
}

Each class has a collection to the other 2 classes, don't ask why, but I need to map this to a database. Nhibernate generates 3 tables, 2 of them with 2 fields and the third one with the 3 id fields from all the classes, o this third table just 2 fields are part of a Primary Key. I also tryed to asign the table name for the 3 relationships, and NHibernate generates just one table with the 3 fields, but again, only 2 of them are part of the Primery Key. I'm assuming that the 3 field must be part of the primary key given this type of mapping.

The problem is that I can't add items to either collection (I also tried adding the item to the other side class, eg: when I add ClassB to ClassA also add ClassA to ClassB to maintaing the relationship), when I tried to save to database, It throws a FOREING KEY exception and all of the field are set correctly.

My question is, what is the best way to map these three classes? Do I need to do anything else? Am I forgeting something?

DisplayName
  • 3,093
  • 5
  • 35
  • 42
ElMangau
  • 51
  • 2
  • 6

1 Answers1

1

I believe you need to give NH some more details about the relations.
Try Writing the full definition in A's mapping and B's mapping:

HasManyToMany(a => a.ClassesB)
     .AsSet()
     .WithTableName("TBL_A_TO_B")
     .WithParentKeyColumn("A_ID")
     .WithChildKeyColumn("B_ID")
     .Cascade.All();
  • Thanks Tamir, but I tryed that too, but the 3 maps pointing to the same TableName with the same results. One question, does the Cascade.All vs Cascade.SaveUpdate makes any diferences on the generated table? – ElMangau Jul 17 '12 at 18:35
  • no it doesnt change the table definition. use diffrent table name for each couple-relation (TBL_A_B,TBL_B_C,TBL_A_C) – Tamir Dresher Jul 18 '12 at 04:46
  • Thanks Tamir, that did the trick!!! I was looking all the problem from another wrong perspective, and your solution open my eyes!!! – ElMangau Jul 18 '12 at 06:19
  • One more thing, I had problems when adding items to the relationships, the NHibernate throws a duplicate key exception when I commit the transaction. I have to add Inverse 3 of the 6 mappings to tell NHibernate that ignore one side of the relation, that indicates to NHibernate that only try to persists the relationship one time, and no two times. I hope this help someone else with the same problem. – ElMangau Jul 18 '12 at 06:25