-
Notifications
You must be signed in to change notification settings - Fork 936
Closed
Description
Upgraded a repository to nhibernate 5.3.5 and ran into sudden null reference exceptions with a few merge operations. This example program shows the behavior, for me running it on nhibernate 5.3.5 and fluent nhibernate 3.1 throws a null reference exception on Merge(), the stack trace for which I will include below. I tried downgrading to 5.2.7 and the error went away.
using System;
using FluentNHibernate.Mapping;
using NHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate.Cfg;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
MergeTestChild child = null;
using (var session = FluentNHibernateHelperService.OpenSession())
{
child = new MergeTestChild()
{
Parent = session.QueryOver<MergeTestParent>().Take(1).SingleOrDefault()
};
}
Console.WriteLine($"New detached instance: {child}");
using (var session = FluentNHibernateHelperService.OpenSession())
{
child = session.Merge(child);
}
Console.WriteLine("Donezo");
Console.ReadKey();
}
}
public class MergeTestParent
{
public virtual int ParentId { get; set; }
public override string ToString() => $"Parent {ParentId}";
}
public class MergeTestParentMap : ClassMap<MergeTestParent>
{
public MergeTestParentMap()
{
Table("merge_test_parent");
Id(x => x.ParentId).GeneratedBy.Identity().Column("parent_id");
}
}
public class MergeTestChild
{
public virtual int ChildId { get; set; }
public virtual MergeTestParent Parent { get; set; }
public override string ToString() => $" Child {ChildId} (Parent {Parent?.ParentId})";
}
public class MergeTestChildMap : ClassMap<MergeTestChild>
{
public MergeTestChildMap()
{
Table("merge_test_child");
Id(x => x.ChildId).GeneratedBy.Identity().Column("child_id");
References(x => x.Parent, "parent_id")
.LazyLoad(Laziness.False)
.NotFound.Ignore()
.Cascade.None()
.Fetch.Join();
}
}
public class FluentNHibernateHelperService
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
InitializeSessionFactory();
return _sessionFactory;
}
}
private static void InitializeSessionFactory()
{
Configuration config =
Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.ConnectionString("Data Source=(local);Initial Catalog=test;Integrated Security=SSPI;Timeout=300;")
)
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<ConsoleApp1.Program>())
.BuildConfiguration();
_sessionFactory = config.BuildSessionFactory();
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
public static IStatelessSession OpenStatelessSession()
{
return SessionFactory.OpenStatelessSession();
}
}
}
Exception thrown: 'System.NullReferenceException' in NHibernate.dll
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>ConsoleApp1.exe</AppDomain><Exception><ExceptionType>System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Object reference not set to an instance of an object.</Message><StackTrace> at NHibernate.Type.ManyToOneType.IsNull(Object owner, ISessionImplementor session)
at NHibernate.Type.EntityType.ResolveIdentifier(Object value, ISessionImplementor session, Object owner)
at NHibernate.Type.EntityType.Replace(Object original, Object target, ISessionImplementor session, Object owner, IDictionary copyCache)
at NHibernate.Type.AbstractType.Replace(Object original, Object target, ISessionImplementor session, Object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
at NHibernate.Type.TypeHelper.Replace(Object[] original, Object[] target, IType[] types, ISessionImplementor session, Object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
at NHibernate.Event.Default.DefaultMergeEventListener.CopyValues(IEntityPersister persister, Object entity, Object target, ISessionImplementor source, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
at NHibernate.Event.Default.DefaultMergeEventListener.MergeTransientEntity(Object entity, String entityName, Object requestedId, IEventSource source, IDictionary copyCache)
at NHibernate.Event.Default.DefaultMergeEventListener.EntityIsTransient(MergeEvent event, IDictionary copyCache)
at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event, IDictionary copiedAlready)
at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event)
at NHibernate.Impl.SessionImpl.FireMerge(MergeEvent event)
at NHibernate.Impl.SessionImpl.Merge(String entityName, Object obj)
at NHibernate.Impl.SessionImpl.Merge[T](T entity)
at ConsoleApp1.Program.Main(String[] args) in C:\source\repos\ConsoleApp1\Program.cs:line 27</StackTrace><ExceptionString>System.NullReferenceException: Object reference not set to an instance of an object.
at NHibernate.Type.ManyToOneType.IsNull(Object owner, ISessionImplementor session)
at NHibernate.Type.EntityType.ResolveIdentifier(Object value, ISessionImplementor session, Object owner)
at NHibernate.Type.EntityType.Replace(Object original, Object target, ISessionImplementor session, Object owner, IDictionary copyCache)
at NHibernate.Type.AbstractType.Replace(Object original, Object target, ISessionImplementor session, Object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
at NHibernate.Type.TypeHelper.Replace(Object[] original, Object[] target, IType[] types, ISessionImplementor session, Object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
at NHibernate.Event.Default.DefaultMergeEventListener.CopyValues(IEntityPersister persister, Object entity, Object target, ISessionImplementor source, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
at NHibernate.Event.Default.DefaultMergeEventListener.MergeTransientEntity(Object entity, String entityName, Object requestedId, IEventSource source, IDictionary copyCache)
at NHibernate.Event.Default.DefaultMergeEventListener.EntityIsTransient(MergeEvent event, IDictionary copyCache)
at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event, IDictionary copiedAlready)
at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event)
at NHibernate.Impl.SessionImpl.FireMerge(MergeEvent event)
at NHibernate.Impl.SessionImpl.Merge(String entityName, Object obj)
at NHibernate.Impl.SessionImpl.Merge[T](T entity)
at ConsoleApp1.Program.Main(String[] args) in C:\source\repos\ConsoleApp1\Program.cs:line 27</ExceptionString></Exception></TraceRecord>
An unhandled exception of type 'System.NullReferenceException' occurred in NHibernate.dll
Object reference not set to an instance of an object.