diff --git a/src/NHibernate.Test/Async/NHSpecificTest/NH3864/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/NH3864/Fixture.cs new file mode 100644 index 00000000000..14e612e9e89 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/NH3864/Fixture.cs @@ -0,0 +1,157 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using NHibernate.Linq; +using NUnit.Framework; +using System.Collections.Generic; +using System.Linq; + +namespace NHibernate.Test.NHSpecificTest.NH3864 +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : BugTestCase + { + protected override void OnSetUp() + { + Clear2ndLevelCache(); + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var p1 = new Person() { Name = "A" }; + var p1c1 = new Person() { Name = "AA" }; + var p1c2 = new Person() { Name = "AB" }; + var p1c3 = new Person() { Name = "AC" }; + p1.Children = new HashSet(new[] { p1c1, p1c2, p1c3 }); + session.Save(p1); + + var p2 = new Person() { Name = "B" }; + var p2c1 = new Person() { Name = "BA" }; + var p2c2 = new Person() { Name = "BB" }; + var p2c3 = new Person() { Name = "BC" }; + p2.Children = new HashSet(new[] { p2c1, p2c2, p2c3 }); + session.Save(p2); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.Delete("from Person"); + transaction.Commit(); + } + } + + [Test] + public async Task CacheableMulticriteria_QueryOverWithAliasedJoinQueryOverAsync() + { + foreach (var checkCache in new[] { false, true }) + { + using (var sqlLogSpy = new SqlLogSpy()) + { + using (var session = Sfi.OpenSession()) + { + var query = CreateQueryOverWithAliasedJoinQueryOver(session); + + var multiCriteria = session.CreateMultiCriteria(); + multiCriteria.Add("myQuery", query); + multiCriteria.SetCacheable(true); + + var list = (IList)await (multiCriteria.GetResultAsync("myQuery")); + AssertQueryResult(list); + } + + if (checkCache && !string.IsNullOrEmpty(sqlLogSpy.GetWholeLog())) + { + Assert.Fail("SQL executed. 2nd level cache should be used instead."); + } + } + } + } + + [Test] + public async Task CacheableMulticriteria_QueryOverWithJoinAliasAsync() + { + foreach (var checkCache in new[] { false, true }) + { + using (var sqlLogSpy = new SqlLogSpy()) + { + using (var s = Sfi.OpenSession()) + { + var query = CreateQueryOverWithJoinAlias(s); + + var multiCriteria = s.CreateMultiCriteria(); + multiCriteria.Add("myQuery", query); + multiCriteria.SetCacheable(true); + + var list = (IList)await (multiCriteria.GetResultAsync("myQuery")); + AssertQueryResult(list); + } + if (checkCache && !string.IsNullOrEmpty(sqlLogSpy.GetWholeLog())) + { + Assert.Fail("SQL executed. 2nd level cache should be used instead."); + } + } + } + } + + private static void AssertQueryResult(IList list) + { + Assert.AreEqual(6, list.Count, "Returned records count is wrong."); + var person1 = list.FirstOrDefault(p => p.Name == "A"); + Assert.NotNull(person1); + var person2 = list.FirstOrDefault(p => p.Name == "B"); + Assert.NotNull(person2); + + CollectionAssert.AreEquivalent(person1.Children.Select(c => c.Name), new[] { "AA", "AB", "AC" }); + CollectionAssert.AreEquivalent(person2.Children.Select(c => c.Name), new[] { "BA", "BB", "BC" }); + } + + private static IFutureEnumerable CreateCacheableQueryWithSubquery(ISession session) + { + var subQuery = session.Query() + .WithOptions(p => p.SetCacheable(true)); + + var query = session.Query() + .FetchMany(p => p.Children) + .Where(p => subQuery.Contains(p) && p.Parent == null) + .WithOptions(o => o.SetCacheable(true)) + .ToFuture(); + + return query; + } + + private static IQueryOver CreateQueryOverWithJoinAlias(ISession session) + { + Person childAlias = null; + return session.QueryOver() + .Where(p => p.Parent == null) + .JoinAlias(x => x.Children, () => childAlias); + } + + private static IQueryOver CreateQueryOverWithAliasedJoinQueryOver(ISession session) + { + Person childAlias = null; + return session.QueryOver() + .Where(p => p.Parent == null) + .JoinQueryOver(x => x.Children, () => childAlias); + } + + private void Clear2ndLevelCache() + { + Sfi.EvictQueries(); + Sfi.Evict(typeof(Person)); + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH3864/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/NH3864/Fixture.cs new file mode 100644 index 00000000000..3c6076f7bc6 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3864/Fixture.cs @@ -0,0 +1,216 @@ +using NHibernate.Linq; +using NUnit.Framework; +using System.Collections.Generic; +using System.Linq; + +namespace NHibernate.Test.NHSpecificTest.NH3864 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + Clear2ndLevelCache(); + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var p1 = new Person() { Name = "A" }; + var p1c1 = new Person() { Name = "AA" }; + var p1c2 = new Person() { Name = "AB" }; + var p1c3 = new Person() { Name = "AC" }; + p1.Children = new HashSet(new[] { p1c1, p1c2, p1c3 }); + session.Save(p1); + + var p2 = new Person() { Name = "B" }; + var p2c1 = new Person() { Name = "BA" }; + var p2c2 = new Person() { Name = "BB" }; + var p2c3 = new Person() { Name = "BC" }; + p2.Children = new HashSet(new[] { p2c1, p2c2, p2c3 }); + session.Save(p2); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.Delete("from Person"); + transaction.Commit(); + } + } + + [Test] + public void CacheableMulticriteria_QueryOverWithAliasedJoinQueryOver() + { + foreach (var checkCache in new[] { false, true }) + { + using (var sqlLogSpy = new SqlLogSpy()) + { + using (var session = Sfi.OpenSession()) + { + var query = CreateQueryOverWithAliasedJoinQueryOver(session); + + var multiCriteria = session.CreateMultiCriteria(); + multiCriteria.Add("myQuery", query); + multiCriteria.SetCacheable(true); + + var list = (IList)multiCriteria.GetResult("myQuery"); + AssertQueryResult(list); + } + + if (checkCache && !string.IsNullOrEmpty(sqlLogSpy.GetWholeLog())) + { + Assert.Fail("SQL executed. 2nd level cache should be used instead."); + } + } + } + } + + [Test] + public void CacheableFuture_QueryOverWithAliasedJoinQueryOver() + { + foreach (var checkCache in new[] { false, true }) + { + using (var sqlLogSpy = new SqlLogSpy()) + { + using (var s = Sfi.OpenSession()) + { + var query = CreateQueryOverWithAliasedJoinQueryOver(s) + .Cacheable() + .Future(); + + var list = query.ToList(); + AssertQueryResult(list); + } + if (checkCache && !string.IsNullOrEmpty(sqlLogSpy.GetWholeLog())) + { + Assert.Fail("SQL executed. 2nd level cache should be used instead."); + } + } + } + } + + [Test] + public void CacheableMulticriteria_QueryOverWithJoinAlias() + { + foreach (var checkCache in new[] { false, true }) + { + using (var sqlLogSpy = new SqlLogSpy()) + { + using (var s = Sfi.OpenSession()) + { + var query = CreateQueryOverWithJoinAlias(s); + + var multiCriteria = s.CreateMultiCriteria(); + multiCriteria.Add("myQuery", query); + multiCriteria.SetCacheable(true); + + var list = (IList)multiCriteria.GetResult("myQuery"); + AssertQueryResult(list); + } + if (checkCache && !string.IsNullOrEmpty(sqlLogSpy.GetWholeLog())) + { + Assert.Fail("SQL executed. 2nd level cache should be used instead."); + } + } + } + } + + [Test] + public void CacheableFuture_QueryOverWithJoinAlias() + { + foreach (var checkCache in new[] { false, true }) + { + using (var sqlLogSpy = new SqlLogSpy()) + { + using (var s = Sfi.OpenSession()) + { + var query = CreateQueryOverWithJoinAlias(s) + .Cacheable() + .Future(); + + var list = query.ToList(); + AssertQueryResult(list); + } + if (checkCache && !string.IsNullOrEmpty(sqlLogSpy.GetWholeLog())) + { + Assert.Fail("SQL executed. 2nd level cache should be used instead."); + } + } + } + } + + [Test] + public void CacheableFuture_QueryWithSubQuery() + { + foreach (var checkCache in new[] { false, true }) + { + using (var sqlLogSpy = new SqlLogSpy()) + { + using (var session = Sfi.OpenSession()) + { + var query = CreateCacheableQueryWithSubquery(session); + + var list = query.ToList(); + AssertQueryResult(list); + } + if (checkCache && !string.IsNullOrEmpty(sqlLogSpy.GetWholeLog())) + { + Assert.Fail("SQL executed. 2nd level cache should be used instead."); + } + } + } + } + + private static void AssertQueryResult(IList list) + { + Assert.AreEqual(6, list.Count, "Returned records count is wrong."); + var person1 = list.FirstOrDefault(p => p.Name == "A"); + Assert.NotNull(person1); + var person2 = list.FirstOrDefault(p => p.Name == "B"); + Assert.NotNull(person2); + + CollectionAssert.AreEquivalent(person1.Children.Select(c => c.Name), new[] { "AA", "AB", "AC" }); + CollectionAssert.AreEquivalent(person2.Children.Select(c => c.Name), new[] { "BA", "BB", "BC" }); + } + + private static IFutureEnumerable CreateCacheableQueryWithSubquery(ISession session) + { + var subQuery = session.Query() + .WithOptions(p => p.SetCacheable(true)); + + var query = session.Query() + .FetchMany(p => p.Children) + .Where(p => subQuery.Contains(p) && p.Parent == null) + .WithOptions(o => o.SetCacheable(true)) + .ToFuture(); + + return query; + } + + private static IQueryOver CreateQueryOverWithJoinAlias(ISession session) + { + Person childAlias = null; + return session.QueryOver() + .Where(p => p.Parent == null) + .JoinAlias(x => x.Children, () => childAlias); + } + + private static IQueryOver CreateQueryOverWithAliasedJoinQueryOver(ISession session) + { + Person childAlias = null; + return session.QueryOver() + .Where(p => p.Parent == null) + .JoinQueryOver(x => x.Children, () => childAlias); + } + + private void Clear2ndLevelCache() + { + Sfi.EvictQueries(); + Sfi.Evict(typeof(Person)); + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH3864/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/NH3864/Mappings.hbm.xml new file mode 100644 index 00000000000..13a053bcf8c --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3864/Mappings.hbm.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/NHibernate.Test/NHSpecificTest/NH3864/Person.cs b/src/NHibernate.Test/NHSpecificTest/NH3864/Person.cs new file mode 100644 index 00000000000..7de6076091d --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3864/Person.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH3864 +{ + public class Person + { + public virtual int Id { get; set; } + + public virtual string Name { get; set; } + + public virtual Person Parent { get; set; } + + public virtual ISet Children { get; set; } + } +} \ No newline at end of file