This is fragment of my database project, and this is fragment of auto generated DB by Fluent NHibernate
And these are my entities and mapping classes in Fluent NHibernate of above DB project.
Entities:
public class BaseEntity<T> where T : BaseEntity<T> {
public virtual int Id { get; set; }
...
}
public class Person<T> : BaseEntity<T> where T : BaseEntity<T> {
public virtual string FirstName { get; set; }
public virtual string SecondName { get; set; }
public virtual string LastName { get; set; }
public virtual string PESEL { get; set; }
public virtual DateTime BirthDate { get; set; }
public virtual string City { get; set; }
public virtual string PostalCode { get; set; }
public virtual string Street { get; set; }
public virtual string HouseNr { get; set; }
public virtual string ApartmentNr { get; set; }
public virtual string PhoneNr { get; set; }
public virtual string Email { get; set; }
}
public class DrivingLicense : BaseEntity<DrivingLicense> {
#region Relations
public virtual IList<DrivingLicensePermissions> DrivingLicensePermissions { get; set; }
public virtual Student Student { get; set; }
#endregion
public virtual DateTime IssueDate { get; set; }
public virtual string DrivingLicenseNr { get; set; }
}
public class DrivingLicensePermissions : BaseEntity<DrivingLicensePermissions> {
#region Relations
public virtual DrivingLicense DrivingLicense { get; set; }
#endregion
public virtual DrivingLicenseCategory Category { get; set; }
}
Mappings:
class StudentMap : ClassMap<Student> {
public StudentMap() {
Id(x => x.Id);
Map(x => x.FirstName).Not.Nullable().Length(25);
Map(x => x.SecondName).Nullable().Length(25);
Map(x => x.LastName).Not.Nullable().Length(50);
Map(x => x.PESEL).Nullable().Length(11);
Map(x => x.BirthDate).Not.Nullable();
Map(x => x.City).Not.Nullable().Length(50);
Map(x => x.PostalCode).Nullable().Length(6);
Map(x => x.Street).Not.Nullable().Length(50);
Map(x => x.HouseNr).Not.Nullable().Length(10);
Map(x => x.ApartmentNr).Nullable().Length(10);
Map(x => x.PhoneNr).Nullable().Length(20);
Map(x => x.Email).Nullable().Length(100);
References(x => x.DrivingLicense).Nullable().Cascade.All();
References(x => x.User).Nullable().Cascade.All();
HasMany(x => x.Participants).Cascade.All();
}
}
class DrivingLicenseMap : ClassMap<DrivingLicense> {
public DrivingLicenseMap() {
Id(x => x.Id);
Map(x => x.IssueDate).Not.Nullable();
Map(x => x.DrivingLicenseNr).Not.Nullable().Length(20);
HasMany(x => x.DrivingLicensePermissions).Cascade.All();
References(x => x.Student).Not.Nullable();
}
}
class DrivingLicensePermissionsMap : ClassMap<DrivingLicensePermissions> {
public DrivingLicensePermissionsMap() {
Id(x => x.Id);
Map(x => x.Category).Not.Nullable();
References(x => x.DrivingLicense).Not.Nullable();
}
}
And my problem is this exception: not-null property references a null or transient value Model.Entities.DrivingLicense.Student, while I'm trying to persist Student object like this
session.Save(student);
which has assigned DrivingLicense object to it's DrivingLicense property.
I assume it's caused because of bad mapping - wrong Cascade or lack of Inverse. I tried many combinations and can't get it work. Also is it correct that Student table has DrivingLicense_id and the opposite, DrivingLicense has Student_id column?!
To solve my problem I had to change Reference-to-Reference to HasOne-to-Reference.
Now it looks like this.
Entities have not changed
Mappings:
Thank to this change, circular reference was gone. see it here
There is no DrivingLicense_id in Students table and now I'm able to persist Student entity along with DrivingLicense and it's permissions just by saving student like I did it before.