nhibernate / fluent-nhibernate

Fluent NHibernate!
BSD 3-Clause "New" or "Revised" License
1.66k stars 686 forks source link

fluent NHibernate not saving the foreign key in HasMany. The column remains null #533

Open siphomaribo opened 1 year ago

siphomaribo commented 1 year ago

I am struggling to have the Foreign Keys in my mappings.

My Model looks like this:

public class Accountant: Entity
    {
        public virtual string Name { get; set; }
        public virtual IList<Company> Companies { get; set; }

    }

    public class Company: Entity
    {
        public virtual string Name { get; set; }
        public virtual Subscriber Subscriber { get; set; }
        public virtual Accountant Accountant { get; set; }
        public virtual Funder Funder { get; set; }  
    }

and my Mappings look like this

public class AccountantMap : ClassMap<Accountant>
    {
        public AccountantMap()
        {
            Id(x => x.Id);
            Map(x => x.Name);

            HasMany(x => x.Companies)
               .Inverse()
              .Cascade.All();

            Table("tblAccountant");
        }
    }
 public class CompanyMap : ClassMap<Company>
    {
        public CompanyMap()
        {
            Id(x => x.Id);
            Map(x => x.Name);

            References(x => x.Subscriber).Cascade.SaveUpdate();
            References(x => x.Accountant).Cascade.SaveUpdate();
            References(x => x.Funder).Cascade.SaveUpdate();

            Table("tblCompany");
        }
    }
And so, what I am trying to do, am trying to save the Accountant Object and it must update the foreign key in the table tblCompany

here's how my Save method looks like

public void Create_Accountant()
        {

            var repo = new Repository();

            var companies = new List<Company>();

            companies.Add(repo.GetById<Company>(new Guid("02032BD9-2769-4183-9750-AF1F00A5E191")));
            companies.Add(repo.GetById<Company>(new Guid("F86E8B40-73D2-447E-A525-AF1F00A5E191")));

            var accountant = new Accountant
            {
                Name = "Accountant Simba",

            };

            repo.Save(accountant);

        }

   public void Save<T>(T entity) where T: Entity
        {
            using (var session = _factory.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.SaveOrUpdate(entity);
                        session.Flush();
                        transaction.Commit();
                        //return entity.Id;

                    }
                    catch (Exception)
                    {
                        transaction.Rollback();
                        throw;
                    }
                }
            }
        }

After the code has executed, this is what in my Database

image

You'd notice that the Account_id column is empty and it should not be empty.

Someone, please help me, what am I doing wrong?

Aniketu commented 1 year ago

I'm also facing the same issue. Any solution on this?

TiltonJH commented 2 months ago

Foremost, this is not an issue of FluentNHibernate. FluentNHibernate can only create the configuration and mapping for NHibernate.

Your case is a common behavior of NHibernate.

The example code never assigns any value to the property of Company.Accountant or to the Accountant.Companies. Therefor the property is null. And the database reflects this model state.

If you make your Company.Accountant reference the correct Accountant model, it will do so in the DB as well.

Try something like:

public void Create_Accountant()
{

  var repo = new Repository();

  var companies = new List<Company>();

  companies.Add(repo.GetById<Company>(new Guid("02032BD9-2769-4183-9750-AF1F00A5E191")));
  companies.Add(repo.GetById<Company>(new Guid("F86E8B40-73D2-447E-A525-AF1F00A5E191")));

  var accountant = new Accountant
  {
    Name = "Accountant Simba",
    Companies = companies,
  };

  foreach (var item in companies)
  {
    item.Accountant = accountant;
  }

  repo.Save(accountant);
}