Pergunta

I have a tree stucture model (used composite pattern).
it's class diagram is like this: composite class diagram

database diagram: database diagram

and sample of tree: enter image description here

the problem rise when I want to persist CombatElement tree which its depth is more than one, when I try to persist such object, NHibernate only save the objects which are in the 1st level and ignores the objects which connected to 2nd level object and so:

if I create this tree :

 CombatElement fe = new Formation() { Name = "Alpha Company" };

        fe.Add(new Soldier()
        {
            Name = "Joe",
            Rank = 1
        });
        fe.Add(new Soldier()
        {
            Name = "Jack",
            Rank = 2
        });

        CombatElement platoon =
            new Formation();
        platoon.Name = "1st Platoon";
        fe.Add(platoon);
        platoon.Add(
            new Soldier()
            {
                Name = "Adam",
                Rank = 2

            });
        platoon.Add(
            new Soldier()
            {
                Name = "Arthur",
                Rank = 3

            });

only "Joe", "1st Platoon" and "Jack" will be saved into the database and "Arthur" and "Adam" which are the subelemnts of 1st Platoon will be ignored and won't be saved!!

here is mapping classes:

public class CombatElementMap:ClassMap<CombatElement>
{
    public CombatElementMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name).Not.Nullable().Length(100);
    }

}

///////////////////////////

public class FormationMap:ClassMap<Formation>
{
    public FormationMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        HasMany(x => x.Elements).Cascade.AllDeleteOrphan();
    }
}

///////////////////////////

 public class SoldierMap:ClassMap<Soldier>
{
    public SoldierMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Rank);
    }
}

I have cascaded the Formation objects, but the problem is still persist. why this happens? It just confusing me!!

Foi útil?

Solução

You are using inheritance in your class structure, to properly instrcut nHibernate to store the base class and sub class properties, you'll have to redefine your mappings and maybe the objects a little bit

Basically you should use SubClassMap instead of ClassMap for all sub classes and only define new properties in those sub class mappings.

I've added some code for the elements (best guess according to your diagram)

public abstract class CombatElement
{
    public CombatElement()
    {
        Elements = new List<CombatElement>();
    }

    public virtual Guid Id { get; set; }

    public virtual string Name { get; set; }

    public virtual IList<CombatElement> Elements { get; set; }

    public virtual void Add(CombatElement element)
    {
        Elements.Add(element);
    }
}

public class Formation : CombatElement
{
}

public class Soldier : CombatElement
{
    public virtual int Rank { get; set; }
}

And the new mapping would look like this:

public class CombatElementMap : ClassMap<CombatElement>
{
    public CombatElementMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name).Not.Nullable().Length(100);
        HasMany(x => x.Elements)
            .AsBag()
            .Fetch.Join()
            .Cascade.AllDeleteOrphan();
    }

}

public class FormationMap : SubclassMap<Formation>
{
    public FormationMap()
    {
        //Id(x => x.Id).GeneratedBy.GuidComb();
    }
}

public class SoldierMap : SubclassMap<Soldier>
{
    public SoldierMap()
    {
        //Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Rank);
    }
}

also make sure you call .Flush after saving your entities, otherwise it might not get stored in your database.

session.Save(fe);
session.Flush();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top