0

I am trying to save an object Allocation :

public class Allocation : DomainEntity
{
    public Allocation()
    {
        this.AllocationsTitres = new List<AllocationTitre>();
    }

    public virtual int Id { get; set; }
    public virtual int IdProfil { get; set; }
    public virtual DateTime DateDebut { get; set; }
    public virtual DateTime? DateFin { get; set; }
    public virtual DateTime DateMAJ { get; set; }
    public virtual IList<AllocationTitre> AllocationsTitres { get; set; }

    public virtual void AddAllocationTitre(AllocationTitre allocationTitre)
    {
        allocationTitre.Allocation = this;
        this.AllocationsTitres.Add(allocationTitre);
    }
}

That contains a collection of AllocationTitres :

public class AllocationTitre : DomainEntity
{
    public virtual Allocation Allocation { get; set; }
    public virtual Titre Titre { get; set; }
    public virtual decimal TauxRepartition { get; set; }
}

The AllocationTitre possesses a reference to the Allocation. The table AllocationTitre has a composite id and the entity is mapped as follows :

public class AllocationTitreMap : ClassMap<AllocationTitre>
{
    public AllocationTitreMap()
    {
        Table("MdtArb_AllocationTitre");
        LazyLoad();

        CompositeId()
          .KeyReference(x => x.Allocation, "IdAllocation")
          .KeyReference(x => x.Titre, "CodTitr");

        Map(x => x.TauxRepartition).Column("TauxRepartition").Not.Nullable();
    }
}

The parent class Allocation is mapped as follows :

public class AllocationMap : ClassMap<Allocation>
{
    public AllocationMap()
    {
        Table("MdtArb_Allocation");
        LazyLoad();

        Id(x => x.Id).Column("IdAllocation").GeneratedBy.Identity().Not.Nullable();
        Map(x => x.IdProfil).Column("IdProfil").Not.Nullable();
        Map(x => x.DateDebut).Column("DateDebut").Not.Nullable();
        Map(x => x.DateFin).Column("DateFin").Nullable();
        Map(x => x.DateMAJ).Column("DateMAJ").Not.Nullable();

        HasMany(x => x.AllocationsTitres)
                  .Inverse()
                  .Cascade.All()
                  .KeyColumn("IdAllocation")
                  .Table("[MdtArb_AllocationTitre]");
    }
}

I'm trying to create a new Allocation which contains a List of AllocationTitre and get everything saved to the database, with the following code :

        Allocation a = new Allocation()
        {
            IdProfil = 1,
            DateDebut = DateTime.Today,
            DateMAJ = DateTime.Today,
            AllocationsTitres = new List<AllocationTitre>(),
        };

        AllocationTitre at = new AllocationTitre()
        {
            TauxRepartition = 25,
            Titre = new Titre() { CodeTitre = 12 },
        };

        AllocationTitre at2 = new AllocationTitre()
        {
            TauxRepartition = 75,
            Titre = new Titre() { CodeTitre = 15 },
        };

        a.AddAllocationTitre(at);
        a.AddAllocationTitre(at2);

        var repository = AEContainer.Resolve<IRepositoryMandatArbitrageAllocation>();
        a = repository.Create(a);

note that the AddAllocationTitre() method adds a reference to the Allocation on the AllocationTitre.

The Create() method contains the following :

public Allocation Create(Allocation a)
{
    //Create an NHibernate.ISession
    var session = AEContainer.Resolve<IPersistanceService>().GetSession();
    //Save
    var idPostSave = session.Save(a);
    //Return the updated object
    return this.GetById((int)idPostSave);
}

I have tried to use HasMany() with different Cascade mod on the parent class. I have tried using References() and HasOne() on the child class. I have tried using and not using Inverse() and so far I always manage to save the Allocation properly with a new id, but the AllocationTitre are never saved in the database.

I think the issue comes from the composite id in the AllocationTitre mapping but I haven't found a workarround.

What am I missing ?

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141
WizLiz
  • 2,068
  • 5
  • 25
  • 39

1 Answers1

0

Try to specify UnsavedValue explicitly for your composite id mapping:

CompositeId()
    .KeyReference(x => x.Allocation, "IdAllocation")
    .KeyReference(x => x.Titre, "CodTitr");
    .UnsavedValue("any");

That should instruct NHibernate to treat all not present in session objects as new. Read spec for other possible UnsavedValue values.

Roman Artiukhin
  • 2,200
  • 1
  • 9
  • 19