Open
Description
After upgrading an old legacy project from NH 5.2.7 to 5.5.2 I encountered a peculiar regression bug:
- Root Entity has an Id property having an enum type, and a one-to-many relationship with another entity
- Second level cache and query cache is used for querying the Entity; child collection is fetched eagerly in the query in question
- First execution of the query (with unpopulated cache) works; subsequent executions fail with
NullReferenceException
thrown inTypeHelper
.
Example model:
class Entity
{
private readonly ICollection<ChildEntity> _children = new List<ChildEntity>();
public virtual EntityId Id { get; protected set; }
public virtual IEnumerable<ChildEntity> Children => _children.AsEnumerable();
}
class ChildEntity
{
public virtual int Id { get; protected set; }
}
enum EntityId
{
Id1,
Id2
}
Mapping:
mapper.Class<Entity>(
rc =>
{
rc.Id(x => x.Id);
rc.Bag(
x => x.Children,
m =>
{
m.Access(Accessor.Field);
m.Key(k => k.Column("EntityId"));
},
r => r.OneToMany());
rc.Cache(
cm =>
{
cm.Include(CacheInclude.All);
cm.Usage(CacheUsage.ReadWrite);
});
});
mapper.Class<ChildEntity>(
rc =>
{
rc.Id(x => x.Id);
rc.Cache(
cm =>
{
cm.Include(CacheInclude.All);
cm.Usage(CacheUsage.ReadWrite);
});
});
Query:
session
.Query<Entity>()
.FetchMany(x => x.Children)
.WithOptions(opt => opt.SetCacheable(true))
.ToList();
Exception thrown on second and all subsequent query executions:
NHibernate.Exceptions.GenericADOException : Could not execute query[SQL: SQL not available]
----> System.NullReferenceException : Object reference not set to an instance of an object.
at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, Object filterConnection) in C:\dev\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 563
at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) in C:\dev\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 523
at NHibernate.Impl.AbstractSessionImpl.List[T](IQueryExpression query, QueryParameters parameters) in C:\dev\nhibernate-core\src\NHibernate\Impl\AbstractSessionImpl.cs:line 182
at NHibernate.Impl.AbstractQueryImpl2.List[T]() in C:\dev\nhibernate-core\src\NHibernate\Impl\AbstractQueryImpl2.cs:line 111
at NHibernate.Linq.DefaultQueryProvider.ExecuteList[TResult](Expression expression) in C:\dev\nhibernate-core\src\NHibernate\Linq\DefaultQueryProvider.cs:line 111
at NHibernate.Linq.NhQueryable`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() in C:\dev\nhibernate-core\src\NHibernate\Linq\NhQueryable.cs:line 65
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at NHibernate.Test.NHSpecificTest.GHXXXX.FixtureByCode.LoadEntityByNameWithQueryCache() in C:\dev\nhibernate-core\src\NHibernate.Test\NHSpecificTest\GHXXXX\FixtureByCode.cs:line 108
at NHibernate.Test.NHSpecificTest.GHXXXX.FixtureByCode.LoadsEntityWithEnumIdAndChildrenUsingQueryCache() in C:\dev\nhibernate-core\src\NHibernate.Test\NHSpecificTest\GHXXXX\FixtureByCode.cs:line 95
--NullReferenceException
at NHibernate.Type.TypeHelper.InitializeCollections(Object[] cacheRow, Object[] assembleRow, IDictionary`2 collectionIndexes, ISessionImplementor session) in C:\dev\nhibernate-core\src\NHibernate\Type\TypeHelper.cs:line 137
at NHibernate.Cache.StandardQueryCache.InitializeCollections(ICacheAssembler[] returnTypes, ISessionImplementor session, IList assembleResult, IList cacheResult) in C:\dev\nhibernate-core\src\NHibernate\Cache\StandardQueryCache.cs:line 554
at NHibernate.Cache.StandardQueryCache.GetResultFromCacheable(QueryKey key, ICacheAssembler[] returnTypes, Boolean isNaturalKeyLookup, ISessionImplementor session, IList cacheable) in C:\dev\nhibernate-core\src\NHibernate\Cache\StandardQueryCache.cs:line 582
at NHibernate.Cache.StandardQueryCache.Get(QueryKey key, QueryParameters queryParameters, ICacheAssembler[] returnTypes, ISet`1 spaces, ISessionImplementor session) in C:\dev\nhibernate-core\src\NHibernate\Cache\StandardQueryCache.cs:line 147
at NHibernate.Cache.QueryCacheExtensions.Get(IQueryCache queryCache, QueryKey key, QueryParameters queryParameters, ICacheAssembler[] returnTypes, ISet`1 spaces, ISessionImplementor session) in C:\dev\nhibernate-core\src\NHibernate\Cache\IQueryCache.cs:line 147
at NHibernate.Loader.Loader.GetResultFromQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IQueryCache queryCache, QueryKey key) in C:\dev\nhibernate-core\src\NHibernate\Loader\Loader.cs:line 1943
at NHibernate.Loader.Loader.ListUsingQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces) in C:\dev\nhibernate-core\src\NHibernate\Loader\Loader.cs:line 1887
at NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces) in C:\dev\nhibernate-core\src\NHibernate\Loader\Loader.cs:line 1842
at NHibernate.Loader.Hql.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters) in C:\dev\nhibernate-core\src\NHibernate\Loader\Hql\QueryLoader.cs:line 302
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters) in C:\dev\nhibernate-core\src\NHibernate\Hql\Ast\ANTLR\QueryTranslatorImpl.cs:line 156
at NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results) in C:\dev\nhibernate-core\src\NHibernate\Engine\Query\HQLQueryPlan.cs:line 115
at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, Object filterConnection) in C:\dev\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 553
[...]
Metadata
Metadata
Assignees
Labels
No labels