Skip to content

Commit e2e56f6

Browse files
bahusoidhazzik
andauthored
Implement dynamic batch loading algorithm (#2959)
Fixes #1316 Co-authored-by: Alex Zaytsev <hazzik@gmail.com>
1 parent 2e40895 commit e2e56f6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1533
-87
lines changed

src/NHibernate.Test/Async/CacheTest/BatchableCacheFixture.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using NHibernate.Cache;
1616
using NHibernate.Cfg;
1717
using NHibernate.Linq;
18+
using NHibernate.Loader;
1819
using NHibernate.Multi;
1920
using NHibernate.Test.CacheTest.Caches;
2021
using NUnit.Framework;
@@ -24,9 +25,17 @@ namespace NHibernate.Test.CacheTest
2425
{
2526
using System.Threading.Tasks;
2627
using System.Threading;
27-
[TestFixture]
28+
[TestFixture(BatchFetchStyle.Dynamic)]
29+
[TestFixture(BatchFetchStyle.Legacy)]
2830
public class BatchableCacheFixtureAsync : TestCase
2931
{
32+
private readonly BatchFetchStyle _fetchStyle;
33+
34+
public BatchableCacheFixtureAsync(BatchFetchStyle fetchStyle)
35+
{
36+
_fetchStyle = fetchStyle;
37+
}
38+
3039
protected override string[] Mappings => new[]
3140
{
3241
"CacheTest.ReadOnly.hbm.xml",
@@ -43,6 +52,7 @@ protected override void Configure(Configuration configuration)
4352
configuration.SetProperty(Environment.UseQueryCache, "true");
4453
configuration.SetProperty(Environment.GenerateStatistics, "true");
4554
configuration.SetProperty(Environment.CacheProvider, typeof(BatchableCacheProvider).AssemblyQualifiedName);
55+
configuration.SetProperty(Environment.BatchFetchStyle, _fetchStyle.ToString());
4656
}
4757

4858
protected override void OnSetUp()

src/NHibernate.Test/Async/CacheTest/BatchableCacheSubclassFixture.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,24 @@
1515
using NHibernate.Cache;
1616
using NHibernate.Cfg;
1717
using NHibernate.DomainModel;
18+
using NHibernate.Loader;
1819
using NHibernate.Test.CacheTest.Caches;
1920
using NUnit.Framework;
2021

2122
namespace NHibernate.Test.CacheTest
2223
{
2324
using System.Threading.Tasks;
24-
[TestFixture]
25+
[TestFixture(BatchFetchStyle.Dynamic)]
26+
[TestFixture(BatchFetchStyle.Legacy)]
2527
public class BatchableCacheSubclassFixtureAsync : TestCase
2628
{
29+
private readonly BatchFetchStyle _fetchStyle;
30+
31+
public BatchableCacheSubclassFixtureAsync(BatchFetchStyle fetchStyle)
32+
{
33+
_fetchStyle = fetchStyle;
34+
}
35+
2736
protected override string[] Mappings
2837
{
2938
get
@@ -56,6 +65,7 @@ protected override void Configure(Configuration configuration)
5665
configuration.SetProperty(Cfg.Environment.UseSecondLevelCache, "true");
5766
configuration.SetProperty(Cfg.Environment.UseQueryCache, "true");
5867
configuration.SetProperty(Cfg.Environment.CacheProvider, typeof(BatchableCacheProvider).AssemblyQualifiedName);
68+
configuration.SetProperty(Cfg.Environment.BatchFetchStyle, _fetchStyle.ToString());
5969
}
6070

6171
protected override void OnSetUp()

src/NHibernate.Test/Async/NHSpecificTest/NH3142/ChildrenTest.cs

+17-1
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,31 @@
1111
using System;
1212
using System.Collections;
1313
using System.Collections.Generic;
14+
using NHibernate.Cfg;
1415
using NHibernate.Driver;
16+
using NHibernate.Loader;
1517
using NUnit.Framework;
1618

1719
namespace NHibernate.Test.NHSpecificTest.NH3142
1820
{
1921
using System.Threading.Tasks;
20-
[TestFixture]
22+
[TestFixture(BatchFetchStyle.Dynamic)]
23+
[TestFixture(BatchFetchStyle.Legacy)]
2124
public class ChildrenTestAsync : BugTestCase
2225
{
26+
private readonly BatchFetchStyle _fetchStyle;
27+
28+
public ChildrenTestAsync(BatchFetchStyle fetchStyle)
29+
{
30+
_fetchStyle = fetchStyle;
31+
}
32+
33+
protected override void Configure(Configuration configuration)
34+
{
35+
base.Configure(configuration);
36+
configuration.SetProperty(Cfg.Environment.BatchFetchStyle, _fetchStyle.ToString());
37+
}
38+
2339
protected override bool AppliesTo(Engine.ISessionFactoryImplementor factory)
2440
{
2541
return !(factory.ConnectionProvider.Driver is OracleManagedDataClientDriver);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Linq;
14+
using NHibernate.Cfg;
15+
using NHibernate.Cfg.MappingSchema;
16+
using NHibernate.Loader;
17+
using NUnit.Framework;
18+
using Environment = NHibernate.Cfg.Environment;
19+
20+
namespace NHibernate.Test.NHSpecificTest.NH3530
21+
{
22+
using System.Threading.Tasks;
23+
using System.Threading;
24+
//NH-3530 (GH-1316)
25+
[TestFixture(BatchFetchStyle.Dynamic)]
26+
[TestFixture(BatchFetchStyle.Legacy)]
27+
public class BatchFetchStyleFixtureAsync : TestCaseMappingByCode
28+
{
29+
private readonly BatchFetchStyle _fetchStyle;
30+
private readonly List<object> _ids = new List<object>();
31+
32+
public BatchFetchStyleFixtureAsync(BatchFetchStyle fetchStyle)
33+
{
34+
_fetchStyle = fetchStyle;
35+
}
36+
37+
protected override void Configure(Configuration configuration)
38+
{
39+
base.Configure(configuration);
40+
configuration.SetProperty(Environment.BatchFetchStyle, _fetchStyle.ToString());
41+
}
42+
43+
[Test]
44+
public async Task CanLoadEntityAsync()
45+
{
46+
await (PrepareEntitiesAsync(2));
47+
48+
using (var session = OpenSession())
49+
{
50+
var proxy = await (session.LoadAsync<Entity>(_ids[0]));
51+
var result = await (session.GetAsync<Entity>(_ids[1]));
52+
53+
Assert.That(result.Name, Is.Not.Null);
54+
55+
var childrenCount = result.Children.Count;
56+
//Assert.That(NHibernateUtil.IsInitialized(proxy), Is.True);
57+
Assert.That(NHibernateUtil.IsInitialized(proxy.Children), Is.True);
58+
Assert.That(childrenCount, Is.EqualTo(4));
59+
}
60+
}
61+
62+
[KnownBug("GH-2960")]
63+
[Test]
64+
public async Task CanLoadComponentEntityAsync()
65+
{
66+
await (PrepareComponentEntitiesAsync(2));
67+
68+
using (var session = OpenSession())
69+
{
70+
var proxy = await (session.LoadAsync<EntityComponent>(_ids[0]));
71+
var result = await (session.GetAsync<EntityComponent>(_ids[1]));
72+
73+
Assert.That(result.Name, Is.Not.Null);
74+
75+
var childrenCount = result.Children.Count;
76+
Assert.That(NHibernateUtil.IsInitialized(proxy.Children), Is.True);
77+
Assert.That(childrenCount, Is.EqualTo(4));
78+
}
79+
}
80+
81+
[Test]
82+
public async Task CanLoadComponentIdEntityAsync()
83+
{
84+
await (PrepareComponentIdEntitiesAsync(2));
85+
86+
using (var session = OpenSession())
87+
{
88+
var proxy = await (session.LoadAsync<EntityComponentId>(_ids[0]));
89+
var result = await (session.GetAsync<EntityComponentId>(_ids[1]));
90+
91+
Assert.That(result.Name, Is.Not.Null);
92+
93+
var childrenCount = result.Children.Count;
94+
Assert.That(NHibernateUtil.IsInitialized(proxy.Children), Is.True);
95+
Assert.That(childrenCount, Is.EqualTo(4));
96+
}
97+
}
98+
99+
[TestCase(1)]
100+
[TestCase(2)]
101+
[TestCase(3)]
102+
[TestCase(4)]
103+
[TestCase(5)]
104+
public async Task CanLoadBatchAsync(int loadCount)
105+
{
106+
await (PrepareEntitiesAsync(5));
107+
108+
using (var session = OpenSession())
109+
{
110+
foreach (var id in _ids.Take(loadCount))
111+
{
112+
await (session.LoadAsync<Entity>(id));
113+
}
114+
115+
var result = await (session.GetAsync<Entity>(_ids[0]));
116+
var result2 = await (session.GetAsync<Entity>(_ids[1]));
117+
var last = await (session.GetAsync<Entity>(_ids.Last()));
118+
119+
var count = result.Children.Count;
120+
Assert.That(result.Name, Is.Not.Null);
121+
Assert.That(last.Name, Is.Not.Null);
122+
Assert.That(NHibernateUtil.IsInitialized(result2.Children), Is.True);
123+
}
124+
}
125+
126+
protected override void OnTearDown()
127+
{
128+
using (var session = OpenSession())
129+
using (var transaction = session.BeginTransaction())
130+
{
131+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
132+
transaction.Commit();
133+
}
134+
}
135+
136+
protected override HbmMapping GetMappings()
137+
{
138+
return EntityMappings.CreateMapping();
139+
}
140+
141+
private async Task PrepareEntitiesAsync(int count, CancellationToken cancellationToken = default(CancellationToken))
142+
{
143+
_ids.Clear();
144+
using (var session = OpenSession())
145+
using (var transaction = session.BeginTransaction())
146+
{
147+
for (int i = 0; i < count; i++)
148+
{
149+
var entity = new Entity { Name = "some name" + 1 };
150+
AddChildren(entity.Children, 4);
151+
_ids.Add((Guid) await (session.SaveAsync(entity, cancellationToken)));
152+
}
153+
154+
await (transaction.CommitAsync(cancellationToken));
155+
}
156+
}
157+
158+
private async Task PrepareComponentEntitiesAsync(int count, CancellationToken cancellationToken = default(CancellationToken))
159+
{
160+
_ids.Clear();
161+
using (var session = OpenSession())
162+
using (var transaction = session.BeginTransaction())
163+
{
164+
for (int i = 0; i < count; i++)
165+
{
166+
var entity = new EntityComponent { Id1 = i, Id2 = i + 1, Name = "some name" + 1 };
167+
AddChildren(entity.Children, 4);
168+
169+
_ids.Add(await (session.SaveAsync(entity, cancellationToken)));
170+
}
171+
172+
await (transaction.CommitAsync(cancellationToken));
173+
}
174+
}
175+
176+
private async Task PrepareComponentIdEntitiesAsync(int count, CancellationToken cancellationToken = default(CancellationToken))
177+
{
178+
_ids.Clear();
179+
using (var session = OpenSession())
180+
using (var transaction = session.BeginTransaction())
181+
{
182+
for (int i = 0; i < count; i++)
183+
{
184+
var entity = new EntityComponentId { Id = new ComponentId { Id1 = i, Id2 = i + 1 }, Name = "some name" + 1 };
185+
AddChildren(entity.Children, 4);
186+
_ids.Add(await (session.SaveAsync(entity, cancellationToken)));
187+
}
188+
189+
await (transaction.CommitAsync(cancellationToken));
190+
}
191+
}
192+
193+
private static void AddChildren<T>(IList<T> list, int count) where T : new()
194+
{
195+
for (int i = 0; i < count; i++)
196+
{
197+
list.Add(new T());
198+
}
199+
}
200+
}
201+
}

src/NHibernate.Test/CacheTest/BatchableCacheFixture.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,25 @@
55
using NHibernate.Cache;
66
using NHibernate.Cfg;
77
using NHibernate.Linq;
8+
using NHibernate.Loader;
89
using NHibernate.Multi;
910
using NHibernate.Test.CacheTest.Caches;
1011
using NUnit.Framework;
1112
using Environment = NHibernate.Cfg.Environment;
1213

1314
namespace NHibernate.Test.CacheTest
1415
{
15-
[TestFixture]
16+
[TestFixture(BatchFetchStyle.Dynamic)]
17+
[TestFixture(BatchFetchStyle.Legacy)]
1618
public class BatchableCacheFixture : TestCase
1719
{
20+
private readonly BatchFetchStyle _fetchStyle;
21+
22+
public BatchableCacheFixture(BatchFetchStyle fetchStyle)
23+
{
24+
_fetchStyle = fetchStyle;
25+
}
26+
1827
protected override string[] Mappings => new[]
1928
{
2029
"CacheTest.ReadOnly.hbm.xml",
@@ -31,6 +40,7 @@ protected override void Configure(Configuration configuration)
3140
configuration.SetProperty(Environment.UseQueryCache, "true");
3241
configuration.SetProperty(Environment.GenerateStatistics, "true");
3342
configuration.SetProperty(Environment.CacheProvider, typeof(BatchableCacheProvider).AssemblyQualifiedName);
43+
configuration.SetProperty(Environment.BatchFetchStyle, _fetchStyle.ToString());
3444
}
3545

3646
protected override void OnSetUp()

src/NHibernate.Test/CacheTest/BatchableCacheSubclassFixture.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,23 @@
55
using NHibernate.Cache;
66
using NHibernate.Cfg;
77
using NHibernate.DomainModel;
8+
using NHibernate.Loader;
89
using NHibernate.Test.CacheTest.Caches;
910
using NUnit.Framework;
1011

1112
namespace NHibernate.Test.CacheTest
1213
{
13-
[TestFixture]
14+
[TestFixture(BatchFetchStyle.Dynamic)]
15+
[TestFixture(BatchFetchStyle.Legacy)]
1416
public class BatchableCacheSubclassFixture : TestCase
1517
{
18+
private readonly BatchFetchStyle _fetchStyle;
19+
20+
public BatchableCacheSubclassFixture(BatchFetchStyle fetchStyle)
21+
{
22+
_fetchStyle = fetchStyle;
23+
}
24+
1625
protected override string[] Mappings
1726
{
1827
get
@@ -45,6 +54,7 @@ protected override void Configure(Configuration configuration)
4554
configuration.SetProperty(Cfg.Environment.UseSecondLevelCache, "true");
4655
configuration.SetProperty(Cfg.Environment.UseQueryCache, "true");
4756
configuration.SetProperty(Cfg.Environment.CacheProvider, typeof(BatchableCacheProvider).AssemblyQualifiedName);
57+
configuration.SetProperty(Cfg.Environment.BatchFetchStyle, _fetchStyle.ToString());
4858
}
4959

5060
protected override void OnSetUp()

0 commit comments

Comments
 (0)