-
Notifications
You must be signed in to change notification settings - Fork 935
Closed
Description
NullReferenceException
in being thrown when trying to query with fetch and where condition on fetched data. This happens with v5.4.0+; v5.3.16 works without issues. Setup is a bit complex, hope that repro code bellow will explain it better.
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Cfg;
using NHibernate;
using NHibernate.Util;
using FluentNHibernate.Mapping;
using NHibernate.Linq;
using NUnit.Framework;
public class Tests
{
private ISessionFactory sessionFactory;
[SetUp]
public void Setup()
{
var config = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString("Server=localhost;Database=test;User Id=sa;Password=Test4000;"))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Tests>())
.BuildConfiguration();
sessionFactory = config.BuildSessionFactory();
}
[Test]
public void Test1()
{
using var session = sessionFactory.OpenSession();
var entities = session.Query<TopEntity>()
.Fetch(e => e.MiddleEntity)
.Where(e => e.MiddleEntity.BottomEntities.Any(e => e.OneMoreEntity != null))
.ToList();
}
}
class TopEntity
{
public virtual int Id { get; set; }
public virtual MiddleEntity MiddleEntity { get; set; }
}
class TopEntityMap : ClassMap<TopEntity>
{
public TopEntityMap()
{
Id(e => e.Id);
References(e => e.MiddleEntity);
}
}
class MiddleEntity
{
public virtual int Id { get; set; }
public virtual ISet<BottomEntity> BottomEntities { get; set; }
}
class MiddleEntityMap : ClassMap<MiddleEntity>
{
public MiddleEntityMap()
{
Id(e => e.Id);
HasMany(e => e.BottomEntities)
.Table("BottomEntity")
.Cascade.All()
.KeyColumn("MiddleEntity_id").Not.KeyNullable()
.Component(e => {
e.ParentReference(x => x.MiddleEntity);
e.References(x => x.OneMoreEntity);
});
}
}
class BottomEntity
{
public virtual MiddleEntity MiddleEntity { get; set; }
public virtual OneMoreEntity OneMoreEntity { get; set; }
public override bool Equals(object? obj)
{
return (obj as BottomEntity)?.MiddleEntity.Id == MiddleEntity.Id;
}
public override int GetHashCode()
{
return MiddleEntity.Id.GetHashCode();
}
}
class BottomEntityMap : ClassMap<BottomEntity>
{
public BottomEntityMap()
{
CompositeId()
.KeyReference(x => x.MiddleEntity, "MiddleEntity_id")
.KeyReference(x => x.OneMoreEntity, "OneMoreEntity_id");
}
}
class OneMoreEntity
{
public virtual int Id { get; set; }
}
class OneMoreEntityMap : ClassMap<OneMoreEntity>
{
public OneMoreEntityMap()
{
Id(e => e.Id);
}
}
Tested with the following database schema:
drop table if exists TopEntity;
create table TopEntity
(
id int primary key,
MiddleEntity_id int not null
);
drop table if exists MiddleEntity;
create table MiddleEntity
(
id int primary key
);
drop table if exists BottomEntity;
create table BottomEntity
(
MiddleEntity_id int not null,
OneMoreEntity_id int not null
);
drop table if exists OneMoreEntity;
create table OneMoreEntity
(
id int primary key
);