I have uploaded a gist the has a working sample, the mapping files, and the full debug log that shows the issue - https://gist.github.com/ravensorb/14193136002adbb3ec2fac07c026f921
Here is the actual exception that I am getting:
ERR: NHibernate.PropertyValueException: Error dehydrating property value for NHibernate.ConsoleTest.IOrderLine.Product ---> NHibernate.HibernateException: Unable to resolve property: Id
at NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(String propertyName)
at NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Object entity, String propertyPath)
at NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Object obj, String propertyName)
at NHibernate.Type.EntityType.GetReferenceValue(Object value, ISessionImplementor session)
at NHibernate.Type.ManyToOneType.NullSafeSet(DbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, DbCommand statement, ISessionImplementor session, Int32 index)
Here is the main part of the code that demonstrates the issue. It seems there may be an issue when working either inheritance with the Id property?
class Program
{
static void Main(string[] args)
{
try
{
var c = new Catalog { Name = "Catalog 1" };
var p = new Product { Name = "Sample Product", SKU = "123456789", MSRP = (decimal)1.0, Catalog = c };
var ol = new OrderLine { Product = p, Price = p.MSRP, Qty = 1 };
var o = new Order { CreatedOn = DateTime.Now, Lines = new List<IOrderLine> { ol } };
if (System.IO.File.Exists("test.db"))
{
System.IO.File.Delete("test.db");
}
var sessionFactory = NHibernateUtils.CreateSessionFactory(SQLiteConfiguration.Standard.UsingFile("test.db"));
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.Save(typeof(IOrder).FullName, o);
transaction.Commit();
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: {0}", ex);
if (ex.InnerException != null) Console.WriteLine("InnerException: {0}", ex.InnerException);
}
Console.WriteLine("Press <ENTER> to exit....");
Console.ReadLine();
}
}
#region Interfaces
public interface IEntity
{
Guid Id { get; set; }
}
public interface ICataglog : IEntity
{
string Name { get; set; }
}
public interface IProduct : IEntity
{
string Name { get; set; }
string SKU { get; set; }
decimal MSRP { get; set; }
ICataglog Catalog { get; set; }
}
public interface IOrder : IEntity
{
DateTime CreatedOn { get; set; }
IList<IOrderLine> Lines { get; set; }
}
public interface IOrderLine : IEntity
{
IProduct Product { get; set; }
int Qty { get; set; }
decimal Price { get; set; }
}
#endregion Interfaces
#region Class Maps
public class CatalogMap : ClassMap<ICataglog>
{
public CatalogMap()
{
Table("tblCatalog");
Id(x => x.Id)
.Column("Id")
.GeneratedBy.Assigned();
Map(x => x.Name);
}
}
public class ProductMap : ClassMap<IProduct>
{
public ProductMap()
{
Table("tblProduct");
Id(x => x.Id)
.Column("Id")
.GeneratedBy.Assigned();
Map(x => x.Name);
Map(x => x.SKU);
Map(x => x.MSRP);
References(x => x.Catalog)
.Cascade.SaveUpdate();
}
}
public class OrderMap : ClassMap<IOrder>
{
public OrderMap()
{
Table("tblOrder");
Id(x => x.Id)
.Column("Id")
.GeneratedBy.Assigned();
Map(x => x.CreatedOn);
HasMany(x => x.Lines)
.Cascade.All()
.KeyColumns.Add("Id");
}
}
public class OrderLineMap : ClassMap<IOrderLine>
{
public OrderLineMap()
{
Table("tbOrderLine");
Id(x => x.Id)
.Column("Id")
.GeneratedBy.Assigned();
Map(x => x.Qty);
Map(x => x.Price);
References(x => x.Product)
.Cascade.SaveUpdate()
.PropertyRef(x => x.Id)
.ForeignKey("productId");
}
}
#endregion Class Maps
public static class NHibernateUtils
{
public static ISessionFactory CreateSessionFactory(IPersistenceConfigurer persistenceConfigurer)
{
return Fluently.Configure()
.Database(persistenceConfigurer)
.Mappings(m =>
{
m.FluentMappings.Add<CatalogMap>();
m.FluentMappings.Add<ProductMap>();
m.FluentMappings.Add<OrderMap>();
m.FluentMappings.Add<OrderLineMap>();
m.FluentMappings.ExportTo(System.Environment.CurrentDirectory);
})
.ExposeConfiguration(c => new SchemaExport(c).Create(false, true))
.BuildConfiguration()
.BuildSessionFactory();
}
}
if you want to see the mapping files that are generated or want to repro the issue - check out the gist