Skip to content

Commit f797ec5

Browse files
authored
Fix InvalidCastException for Future Criteria with aliased fetches (#2444)
Fixes #2440
1 parent cf1cc9c commit f797ec5

File tree

4 files changed

+134
-2
lines changed

4 files changed

+134
-2
lines changed

src/NHibernate.Test/Async/Criteria/SelectModeTest/SelectModeTest.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,72 @@ public async Task OrderedInnerJoinFetchAsync()
480480
}
481481
}
482482

483+
//GH-2440
484+
[Test]
485+
public async Task FetchWithAliasedJoinFutureAsync()
486+
{
487+
using (var session = OpenSession())
488+
{
489+
EntityComplex alias = null;
490+
EntitySimpleChild child1 = null;
491+
var list = (await (session.QueryOver<EntityComplex>(() => alias)
492+
.Where(ec => ec.Id == _parentEntityComplexId)
493+
.JoinQueryOver(() => alias.Child1, () => child1)
494+
.Fetch(SelectMode.Fetch, () => alias.ChildrenList)
495+
.TransformUsing(Transformers.DistinctRootEntity)
496+
.Future()
497+
.GetEnumerableAsync()))
498+
.ToList();
499+
500+
var childList = list[0].ChildrenList;
501+
Assert.That(list[0].ChildrenList.Count, Is.GreaterThan(1));
502+
Assert.That(list[0].ChildrenList, Is.EqualTo(list[0].ChildrenList.OrderByDescending(c => c.OrderIdx)), "wrong order");
503+
}
504+
}
505+
506+
//GH-2440
507+
[Test]
508+
public async Task CacheableFetchWithAliasedJoinFutureAsync()
509+
{
510+
using (var session = OpenSession())
511+
{
512+
EntityComplex alias = null;
513+
EntitySimpleChild child1 = null;
514+
var list = (await (session.QueryOver<EntityComplex>(() => alias)
515+
.Where(ec => ec.Id == _parentEntityComplexId)
516+
.JoinQueryOver(() => alias.Child1, () => child1)
517+
.Fetch(SelectMode.Fetch, () => alias.ChildrenList)
518+
.TransformUsing(Transformers.DistinctRootEntity)
519+
.Cacheable()
520+
.Future()
521+
.GetEnumerableAsync()))
522+
.ToList();
523+
EntityComplex value = null;
524+
Assert.DoesNotThrow(() => value = list[0]);
525+
Assert.That(value, Is.Not.Null);
526+
}
527+
528+
using (var sqlLog = new SqlLogSpy())
529+
using (var session = OpenSession())
530+
{
531+
EntityComplex alias = null;
532+
EntitySimpleChild child1 = null;
533+
var list = session.QueryOver<EntityComplex>(() => alias)
534+
.Where(ec => ec.Id == _parentEntityComplexId)
535+
.JoinQueryOver(() => alias.Child1, () => child1)
536+
.Fetch(SelectMode.Fetch, () => alias.ChildrenList)
537+
.TransformUsing(Transformers.DistinctRootEntity)
538+
.Cacheable()
539+
.Future()
540+
.ToList();
541+
EntityComplex value = null;
542+
Assert.DoesNotThrow(() => value = list[0]);
543+
Assert.That(value, Is.Not.Null);
544+
545+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(0), "Query is expected to be retrieved from cache");
546+
}
547+
}
548+
483549
[Test, Obsolete]
484550
public async Task FetchModeEagerForLazyAsync()
485551
{

src/NHibernate.Test/Criteria/SelectModeTest/SelectModeTest.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,72 @@ public void OrderedInnerJoinFetch()
511511
}
512512
}
513513

514+
//GH-2440
515+
[Test]
516+
public void FetchWithAliasedJoinFuture()
517+
{
518+
using (var session = OpenSession())
519+
{
520+
EntityComplex alias = null;
521+
EntitySimpleChild child1 = null;
522+
var list = session.QueryOver<EntityComplex>(() => alias)
523+
.Where(ec => ec.Id == _parentEntityComplexId)
524+
.JoinQueryOver(() => alias.Child1, () => child1)
525+
.Fetch(SelectMode.Fetch, () => alias.ChildrenList)
526+
.TransformUsing(Transformers.DistinctRootEntity)
527+
.Future()
528+
.GetEnumerable()
529+
.ToList();
530+
531+
var childList = list[0].ChildrenList;
532+
Assert.That(list[0].ChildrenList.Count, Is.GreaterThan(1));
533+
Assert.That(list[0].ChildrenList, Is.EqualTo(list[0].ChildrenList.OrderByDescending(c => c.OrderIdx)), "wrong order");
534+
}
535+
}
536+
537+
//GH-2440
538+
[Test]
539+
public void CacheableFetchWithAliasedJoinFuture()
540+
{
541+
using (var session = OpenSession())
542+
{
543+
EntityComplex alias = null;
544+
EntitySimpleChild child1 = null;
545+
var list = session.QueryOver<EntityComplex>(() => alias)
546+
.Where(ec => ec.Id == _parentEntityComplexId)
547+
.JoinQueryOver(() => alias.Child1, () => child1)
548+
.Fetch(SelectMode.Fetch, () => alias.ChildrenList)
549+
.TransformUsing(Transformers.DistinctRootEntity)
550+
.Cacheable()
551+
.Future()
552+
.GetEnumerable()
553+
.ToList();
554+
EntityComplex value = null;
555+
Assert.DoesNotThrow(() => value = list[0]);
556+
Assert.That(value, Is.Not.Null);
557+
}
558+
559+
using (var sqlLog = new SqlLogSpy())
560+
using (var session = OpenSession())
561+
{
562+
EntityComplex alias = null;
563+
EntitySimpleChild child1 = null;
564+
var list = session.QueryOver<EntityComplex>(() => alias)
565+
.Where(ec => ec.Id == _parentEntityComplexId)
566+
.JoinQueryOver(() => alias.Child1, () => child1)
567+
.Fetch(SelectMode.Fetch, () => alias.ChildrenList)
568+
.TransformUsing(Transformers.DistinctRootEntity)
569+
.Cacheable()
570+
.Future()
571+
.ToList();
572+
EntityComplex value = null;
573+
Assert.DoesNotThrow(() => value = list[0]);
574+
Assert.That(value, Is.Not.Null);
575+
576+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(0), "Query is expected to be retrieved from cache");
577+
}
578+
}
579+
514580
[Test, Obsolete]
515581
public void FetchModeEagerForLazy()
516582
{

src/NHibernate/Async/Multi/QueryBatchItemBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public async Task<int> ProcessResultsSetAsync(DbDataReader reader, CancellationT
7676
var lockModeArray = loader.GetLockModes(queryParameters.LockModes);
7777
var optionalObjectKey = Loader.Loader.GetOptionalObjectKey(queryParameters, Session);
7878
var tmpResults = new List<object>();
79-
var queryCacheBuilder = new QueryCacheResultBuilder(loader);
79+
var queryCacheBuilder = queryInfo.IsCacheable ? new QueryCacheResultBuilder(loader) : null;
8080
var cacheBatcher = queryInfo.CacheBatcher;
8181
var ownCacheBatcher = cacheBatcher == null;
8282
if (ownCacheBatcher)

src/NHibernate/Multi/QueryBatchItemBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ public int ProcessResultsSet(DbDataReader reader)
222222
var lockModeArray = loader.GetLockModes(queryParameters.LockModes);
223223
var optionalObjectKey = Loader.Loader.GetOptionalObjectKey(queryParameters, Session);
224224
var tmpResults = new List<object>();
225-
var queryCacheBuilder = new QueryCacheResultBuilder(loader);
225+
var queryCacheBuilder = queryInfo.IsCacheable ? new QueryCacheResultBuilder(loader) : null;
226226
var cacheBatcher = queryInfo.CacheBatcher;
227227
var ownCacheBatcher = cacheBatcher == null;
228228
if (ownCacheBatcher)

0 commit comments

Comments
 (0)