Component That References Another Entity Can Cause Foreign Key Exception
After updating to Nhibernate 5.0 from Nhibernate 3.1.0.4 and Fluent Nhibernate 2.1.0 from Fluent Nhibernate 1.2.0.712 the following issue started occurring.
I have an object Container which contains a list of Parents. Parents contains a COMPONENT object with a reference to another StringObject object. There are the following tables:
- Container
- Parent - Contains the Component as well.
- StringObject
If I create a Container with two parents and the first parent has a Component and the second doesn't everything works. But If the first has not component and the second doesn't I get a foreign key exception.
Nhibernate doesn't work properly with components. If it isn't a component but a regular domain mapped class to it's own table everything works.
Here is Console APP that shows the issue:
using System;
using System.Collections.Generic;
using FluentNHibernate.Mapping;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
namespace NhibernateReplicateForeignKeyBug
{
class Program
{
private static string connectionString = string.Empty; //PUT YOUR CONNECTIONSTRING
static void Main(string[] args)
{
ISessionFactory sessionFactory = CreateTables();
var session = sessionFactory.OpenSession();
using (ITransaction transaction = session.BeginTransaction())
{
try
{
var EmptyParent = new Parent();
var ParentWithComponentWithObjectRef = new Parent
{
ComponentWithObjectRef = new ComponentWithObjectRef
{
StringObjectRef = new StringObject
{
Name = "TestName"
}
}
};
Container containerThatBreaks = new Container
{
Parents = new List<Parent> { EmptyParent, ParentWithComponentWithObjectRef}
};
Container containerThatWorks = new Container
{
Parents = new List<Parent> { ParentWithComponentWithObjectRef, EmptyParent}
};
session.Save(containerThatBreaks);
transaction.Commit();
Console.Out.WriteLine("Works!");
}
catch(Exception e)
{
transaction.Rollback();
Console.Out.WriteLine("BROKEN!");
Console.Out.WriteLine(e);
}
Console.ReadLine();
}
}
public static ISessionFactory CreateTables()
{
ISessionFactory sessionFactory;
sessionFactory = FluentNHibernate.Cfg.Fluently.Configure()
.Database(
FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
.ConnectionString(connectionString)
)
.Mappings(m =>
{
m.FluentMappings.AddFromAssemblyOf<ParentMap>();
})
.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
.BuildSessionFactory();
return sessionFactory;
}
}
#region Domain
public class Container
{
public virtual Guid Id { get; set; }
public virtual IList<Parent> Parents { get; set; }
}
public class Parent
{
public virtual Guid Id { get; set; }
public virtual ComponentWithObjectRef ComponentWithObjectRef { get; set; }
}
public class ComponentWithObjectRef
{
public virtual StringObject StringObjectRef { get; set; }
}
public class StringObject
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
}
#endregion
#region Mappings
public class ContainerMap : ClassMap<Container>
{
public ContainerMap()
{
Id(x => x.Id);
HasMany(x => x.Parents)
.Cascade.All();
}
}
public class ParentMap : ClassMap<Parent>
{
public ParentMap()
{
Id(x => x.Id);
Component(x => x.ComponentWithObjectRef, c =>
{
c.References(y => y.StringObjectRef)
.ForeignKey()
.Cascade.All();
});
}
}
public class StringObjectMap : ClassMap<StringObject>
{
public StringObjectMap()
{
Id(x => x.Id);
Map(x => x.Name);
// ComponentWithObjectRef(x => x.ComponentWithObjectRef, c =>
// {
// c.References(y => y.StringObjectRef)
// .ForeignKey()
// .Cascade.All();
// });
}
}
#endregion
}
`
Also posted on Nhibernate: https://github.com/nhibernate/nhibernate-core/issues/1616
Hi,
Is there a chance someone could please have a look at this issue? This currently blocks me from upgrading to latest version ad it seems like a small fix.
Thanks, Guy
Hi,
Is there a chance someone could please have a look at this issue? This currently blocks me from upgrading to latest version ad it seems like a small fix.
Thanks, Guy