1

I have to two tables in my database: Patients and Addresses. They are in one-to-one relation throught Address and CorrespodencyAddress fields in Patients.

Here is the code for Patients:

public class Patients
{
    public virtual int Id { get; protected set; }
    public virtual int? IndividualId { get; set; }
    public virtual string First_Name { get; set; }
    public virtual string Last_Name { get; set; }
    public virtual string Pesel { get; set; }
    public virtual string Gender { get; set; }
    public virtual string Height { get; set; }       //wzrost
    public virtual string Comments { get; set; }     //uwagi

    public virtual Adresses Address { get; set; }
    public virtual Adresses CorrespondencyAddress { get; set; }
    public virtual StudyPayer DefaultPayer { get; set; }

    public virtual DateTime? BirthDate { get; set; }
    public virtual string PhoneNumber { get; set; }

    public virtual DateTime? RegistrationDate { get; set; } 
    public virtual IList<Studies> Studies { get; set; } 

    public Patients()
    {
        Studies = new List<Studies>();
    }

    public virtual void AddAddress(Adresses adresses)
    {
        adresses.Patient = this;
        Address = adresses;
    }

    public virtual void AddStudy(Studies studies)
    {
        studies.Patient = this;
        Studies.Add(studies);
    }
}


public class PatientsMap :ClassMap<Patients>
{
    PatientsMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.IndividualId);
        Map(x => x.First_Name);
        Map(x => x.Last_Name);
        Map(x => x.Pesel);
        Map(x => x.Gender);

        if (ConfigurationMap.DbType == DbType.PostgreSql)
        {
            Map(x => x.RegistrationDate).Nullable();
            Map(x => x.BirthDate).Nullable();
        }

        if (ConfigurationMap.DbType == DbType.MsSql)
        {
            Map(x => x.RegistrationDate).CustomSqlType("datetime2").Nullable();
            Map(x => x.BirthDate).CustomSqlType("datetime2").Nullable();    
        }

        Map(x => x.PhoneNumber);
        Map(x => x.Height);
        Map(x => x.Comments);

        References(x => x.Address).Cascade.All();
        References(x => x.CorrespondencyAddress).Cascade.All();

        References(x => x.DefaultPayer);
        HasMany(x => x.Studies).Cascade.All().KeyColumn("patient_id");
    }
}

Here is code for Addresses

public class Adresses
{
    public virtual int Id { get; protected set; }
    public virtual string Street { get; set; }
    public virtual string HomeNumber { get; set; }
    public virtual string PostalCode { get; set; }
    public virtual string City { get; set; }
    public virtual string Country { get; set; }

    public virtual Patients Patient { get; set; }

    public virtual void AddPatient(Patients patient)
    {
        patient.Address = this;
        Patient = patient;
    }

}    


public class AdressesMap : ClassMap<Adresses>
{
    AdressesMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.HomeNumber);
        Map(x => x.Street);
        Map(x => x.PostalCode);
        Map(x => x.City);
        Map(x => x.Country);

        References(x => x.Patient).Cascade.All();
    }
}

As we all know sometimes CorrespodencyAddress is the same as Address, then I'd like to insert NULL into CorrespodencyAddress and it will be meaning it is the same address.

How can I achieve that?

If I do like below that I get "Nullable object must have a value" exception in runtime:

Patients p = new Patients();
p.CorrespondencyAddress = null;

1 Answers1

1

You should change this:

References(x => x.Address).Cascade.All();
References(x => x.CorrespondencyAddress).Cascade.All();

Into this (see .Nullable() setting)

References(x => x.Address).Cascade.All();
References(x => x.CorrespondencyAddress).Nullable().Cascade.All();

Check all the available settings here (scroll down to Fluent NHibernate's equivalent)

Also check this:

public class Patients
{
    ...
    public virtual int? IndividualId { get; set; }

and this mapping:

Map(x => x.IndividualId);

which should be

Map(x => x.IndividualId).Nullable();
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • I expect that you are recieving Exception: *"not-null property references a null or transient value"* - which could be fixed by setting mentioned in my answer: `.Nullable()`. So, if this does not help, could you share your full stack trace? Usually the exception almost has the answer.... For **Nullable object must have a value** check the answer here http://stackoverflow.com/q/1896185/1679310 – Radim Köhler Dec 29 '14 at 18:21
  • The problem wasn't caused by NH but in logging function that was putted before transaction commit and was logging that transacion was commited. I'm working with code made by some other man that used to use many high level libraries (Fluent NH) but don't know a lot about OOP, makes rubbish in code, is lazy gay, etc. Sorry. – Sebastian Xawery Wiśniowiecki Dec 30 '14 at 09:33