Skip to content

Commit d1a7e10

Browse files
authored
Get rid of select queries for each ManyToMany not found ignored element in Criteria and lazy loading (#3396)
1 parent 2d77480 commit d1a7e10

10 files changed

+553
-125
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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 NHibernate.Criterion;
13+
using NHibernate.Transform;
14+
using NUnit.Framework;
15+
16+
namespace NHibernate.Test.NHSpecificTest.NH750
17+
{
18+
using System.Threading.Tasks;
19+
[TestFixture(0)]
20+
[TestFixture(1)]
21+
[TestFixture(2)]
22+
public class ManyToManyFixtureAsync : BugTestCase
23+
{
24+
private int id2;
25+
private readonly int _drivesCount;
26+
private int _withTemplateId;
27+
private int ValidDrivesCount => _drivesCount;
28+
29+
public ManyToManyFixtureAsync(int drivesCount)
30+
{
31+
_drivesCount = drivesCount;
32+
}
33+
34+
protected override void OnSetUp()
35+
{
36+
Drive dr1 = new Drive("Drive 1");
37+
Drive dr2 = new Drive("Drive 2");
38+
Drive dr3 = new Drive("Drive 3");
39+
Device dv1 = new Device("Device 1");
40+
Device dv2 = new Device("Device 2");
41+
var withTemplate = new Device("Device With Device 2 template") { Template = dv2 };
42+
using var s = Sfi.OpenSession();
43+
using var t = s.BeginTransaction();
44+
s.Save(dr1);
45+
s.Save(dr2);
46+
s.Save(dr3);
47+
AddDrive(dv1, dr2);
48+
AddDrive(dv1, dr1);
49+
AddDrive(dv2, dr3);
50+
AddDrive(dv2, dr1);
51+
52+
s.Save(dv1);
53+
id2 = (int) s.Save(dv2);
54+
_withTemplateId = (int)s.Save(withTemplate);
55+
t.Commit();
56+
}
57+
58+
private void AddDrive(Device dv, Drive drive)
59+
{
60+
if(dv.DrivesNotIgnored.Count >= _drivesCount)
61+
return;
62+
dv.DrivesNotIgnored.Add(drive);
63+
}
64+
65+
protected override void OnTearDown()
66+
{
67+
using var s = Sfi.OpenSession();
68+
using var t = s.BeginTransaction();
69+
70+
s.CreateSQLQuery("delete from DriveOfDevice").ExecuteUpdate();
71+
s.Delete("from Device");
72+
s.Delete("from Drive");
73+
t.Commit();
74+
}
75+
76+
[Test]
77+
public async Task QueryOverFetchAsync()
78+
{
79+
using var log = new SqlLogSpy();
80+
using var s = OpenSession();
81+
var dv2 = await (s.QueryOver<Device>()
82+
.Fetch(SelectMode.Fetch, x => x.DrivesNotIgnored)
83+
.Where(Restrictions.IdEq(id2))
84+
.TransformUsing(Transformers.DistinctRootEntity)
85+
.SingleOrDefaultAsync());
86+
87+
Assert.That(NHibernateUtil.IsInitialized(dv2.DrivesNotIgnored), Is.True);
88+
Assert.That(dv2.DrivesNotIgnored, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
89+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
90+
}
91+
92+
[Test]
93+
public async Task QueryOverFetch2Async()
94+
{
95+
using var log = new SqlLogSpy();
96+
using var s = OpenSession();
97+
var withTemplate = await (s.QueryOver<Device>()
98+
.Fetch(SelectMode.Fetch, x => x.Template, x => x.Template.DrivesNotIgnored)
99+
.Where(Restrictions.IdEq(_withTemplateId))
100+
.TransformUsing(Transformers.DistinctRootEntity)
101+
.SingleOrDefaultAsync());
102+
103+
Assert.That(NHibernateUtil.IsInitialized(withTemplate.Template), Is.True);
104+
Assert.That(NHibernateUtil.IsInitialized(withTemplate.Template.DrivesNotIgnored), Is.True);
105+
Assert.That(withTemplate.Template.DrivesNotIgnored, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
106+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
107+
}
108+
109+
[Test]
110+
public async Task HqlFetchAsync()
111+
{
112+
using var log = new SqlLogSpy();
113+
using var s = OpenSession();
114+
var dv2 = await (s.CreateQuery("from Device d left join fetch d.DrivesNotIgnored where d.id = :id")
115+
.SetResultTransformer(Transformers.DistinctRootEntity)
116+
.SetParameter("id", id2)
117+
.UniqueResultAsync<Device>());
118+
119+
Assert.That(NHibernateUtil.IsInitialized(dv2.DrivesNotIgnored), Is.True);
120+
Assert.That(dv2.DrivesNotIgnored, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
121+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
122+
}
123+
124+
[Test]
125+
public async Task HqlFetch2Async()
126+
{
127+
using var log = new SqlLogSpy();
128+
using var s = OpenSession();
129+
var withTemplate = await (s.CreateQuery("from Device t left join fetch t.Template d left join fetch d.DrivesNotIgnored where d.id = :id")
130+
.SetResultTransformer(Transformers.DistinctRootEntity)
131+
.SetParameter("id", id2)
132+
.UniqueResultAsync<Device>());
133+
134+
Assert.That(NHibernateUtil.IsInitialized(withTemplate.Template), Is.True);
135+
Assert.That(NHibernateUtil.IsInitialized(withTemplate.Template.DrivesNotIgnored), Is.True);
136+
Assert.That(withTemplate.Template.DrivesNotIgnored, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
137+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
138+
}
139+
140+
[Test]
141+
public async Task LazyLoadAsync()
142+
{
143+
using var log = new SqlLogSpy();
144+
using var s = OpenSession();
145+
146+
var dv2 = await (s.GetAsync<Device>(id2));
147+
148+
await (NHibernateUtil.InitializeAsync(dv2.DrivesNotIgnored));
149+
Assert.That(NHibernateUtil.IsInitialized(dv2.DrivesNotIgnored), Is.True);
150+
Assert.That(dv2.DrivesNotIgnored, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
151+
// First query for Device, second for Drives collection
152+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(2));
153+
}
154+
}
155+
}

src/NHibernate.Test/Async/NHSpecificTest/NH750/ManyToManyNotFoundIgnoreFixture.cs

+77-41
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ public class ManyToManyNotFoundIgnoreFixtureAsync : BugTestCase
2424
private int id1;
2525
private int id2;
2626
private int _drive2Id;
27+
private int _withTemplateId;
2728
private readonly int _drivesCount;
28-
private int DrivesCountWithOneIgnored => _drivesCount == 0? 0 : _drivesCount - 1;
29+
private int ValidDrivesCount => _drivesCount == 0 ? 0 : _drivesCount - 1;
2930

3031
public ManyToManyNotFoundIgnoreFixtureAsync(int drivesCount)
3132
{
@@ -39,25 +40,26 @@ protected override void OnSetUp()
3940
Drive dr3 = new Drive("Drive 3");
4041
Device dv1 = new Device("Device 1");
4142
Device dv2 = new Device("Device 2");
42-
using (var s = Sfi.OpenSession())
43-
using (var t = s.BeginTransaction())
44-
{
45-
s.Save(dr1);
46-
_drive2Id = (int)s.Save(dr2);
47-
s.Save(dr3);
48-
AddDrive(dv1, dr2);
49-
AddDrive(dv1, dr1);
50-
AddDrive(dv2, dr3);
51-
AddDrive(dv2, dr1);
52-
53-
id1 = (int) s.Save(dv1);
54-
id2 = (int) s.Save(dv2);
55-
s.Flush();
56-
57-
s.Clear();
58-
s.Delete(dr3);
59-
t.Commit();
60-
}
43+
var withTemplate = new Device("Device With Device 2 template") { Template = dv2 };
44+
45+
using var s = Sfi.OpenSession();
46+
using var t = s.BeginTransaction();
47+
s.Save(dr1);
48+
_drive2Id = (int)s.Save(dr2);
49+
s.Save(dr3);
50+
AddDrive(dv1, dr2);
51+
AddDrive(dv1, dr1);
52+
AddDrive(dv2, dr3);
53+
AddDrive(dv2, dr1);
54+
55+
id1 = (int) s.Save(dv1);
56+
id2 = (int) s.Save(dv2);
57+
_withTemplateId = (int)s.Save(withTemplate);
58+
s.Flush();
59+
60+
s.Clear();
61+
s.Delete(dr3);
62+
t.Commit();
6163
}
6264

6365
private void AddDrive(Device dv, Drive drive)
@@ -87,11 +89,13 @@ public async Task DeviceOfDriveAsync()
8789
{
8890
dv1 = (Device) await (s.LoadAsync(typeof(Device), id1));
8991
dv2 = (Device) await (s.LoadAsync(typeof(Device), id2));
92+
await (NHibernateUtil.InitializeAsync(dv1.Drives));
93+
await (NHibernateUtil.InitializeAsync(dv2.Drives));
9094
}
9195

9296
Assert.That(dv1.Drives, Has.Count.EqualTo(_drivesCount).And.None.Null);
9397
// Verify one is missing
94-
Assert.That(dv2.Drives, Has.Count.EqualTo(DrivesCountWithOneIgnored).And.None.Null);
98+
Assert.That(dv2.Drives, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
9599

96100
//Make sure that flush didn't touch not-found="ignore" records for not modified collection
97101
using (var s = Sfi.OpenSession())
@@ -102,7 +106,7 @@ public async Task DeviceOfDriveAsync()
102106
await (t.CommitAsync());
103107
}
104108

105-
await (VerifyResultAsync(expectedInCollection: DrivesCountWithOneIgnored, expectedInDb: _drivesCount, msg: "not modified collection"));
109+
await (VerifyResultAsync(expectedInCollection: ValidDrivesCount, expectedInDb: _drivesCount, msg: "not modified collection"));
106110

107111
// Many-to-many clears collection and recreates it so not-found ignore records are lost
108112
// Note: It's not the case when no valid records are present, so loaded Drives collection is empty
@@ -139,17 +143,34 @@ async Task VerifyResultAsync(int expectedInCollection, int expectedInDb, string
139143
[Test]
140144
public async Task QueryOverFetchAsync()
141145
{
142-
using (var s = OpenSession())
143-
{
144-
var dv2 = await (s.QueryOver<Device>()
145-
.Fetch(SelectMode.Fetch, x => x.Drives)
146-
.Where(Restrictions.IdEq(id2))
147-
.TransformUsing(Transformers.DistinctRootEntity)
148-
.SingleOrDefaultAsync());
149-
150-
Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
151-
Assert.That(dv2.Drives, Has.Count.EqualTo(DrivesCountWithOneIgnored).And.None.Null);
152-
}
146+
using var log = new SqlLogSpy();
147+
using var s = OpenSession();
148+
var dv2 = await (s.QueryOver<Device>()
149+
.Fetch(SelectMode.Fetch, x => x.Drives)
150+
.Where(Restrictions.IdEq(id2))
151+
.TransformUsing(Transformers.DistinctRootEntity)
152+
.SingleOrDefaultAsync());
153+
154+
Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
155+
Assert.That(dv2.Drives, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
156+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
157+
}
158+
159+
[Test]
160+
public async Task QueryOverFetch2Async()
161+
{
162+
using var log = new SqlLogSpy();
163+
using var s = OpenSession();
164+
var withTemplate = await (s.QueryOver<Device>()
165+
.Fetch(SelectMode.Fetch, x => x.Template, x => x.Template.Drives)
166+
.Where(Restrictions.IdEq(_withTemplateId))
167+
.TransformUsing(Transformers.DistinctRootEntity)
168+
.SingleOrDefaultAsync());
169+
170+
Assert.That(NHibernateUtil.IsInitialized(withTemplate.Template), Is.True);
171+
Assert.That(NHibernateUtil.IsInitialized(withTemplate.Template.Drives), Is.True);
172+
Assert.That(withTemplate.Template.Drives, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
173+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
153174
}
154175

155176
[Test]
@@ -163,21 +184,36 @@ public async Task HqlFetchAsync()
163184
.UniqueResultAsync<Device>());
164185

165186
Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
166-
Assert.That(dv2.Drives, Has.Count.EqualTo(DrivesCountWithOneIgnored).And.None.Null);
187+
Assert.That(dv2.Drives, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
188+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
189+
}
190+
191+
[Test]
192+
public async Task HqlFetch2Async()
193+
{
194+
using var log = new SqlLogSpy();
195+
using var s = OpenSession();
196+
var withTemplate = await (s.CreateQuery("from Device t left join fetch t.Template d left join fetch d.Drives where d.id = :id")
197+
.SetResultTransformer(Transformers.DistinctRootEntity)
198+
.SetParameter("id", id2)
199+
.UniqueResultAsync<Device>());
200+
201+
Assert.That(NHibernateUtil.IsInitialized(withTemplate.Template), Is.True);
202+
Assert.That(NHibernateUtil.IsInitialized(withTemplate.Template.Drives), Is.True);
203+
Assert.That(withTemplate.Template.Drives, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
167204
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
168205
}
169206

170207
[Test]
171208
public async Task LazyLoadAsync()
172209
{
173-
using (var s = OpenSession())
174-
{
175-
var dv2 = await (s.GetAsync<Device>(id2));
176-
await (NHibernateUtil.InitializeAsync(dv2.Drives));
210+
using var s = OpenSession();
177211

178-
Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
179-
Assert.That(dv2.Drives, Has.Count.EqualTo(DrivesCountWithOneIgnored).And.None.Null);
180-
}
212+
var dv2 = await (s.GetAsync<Device>(id2));
213+
using var log = new SqlLogSpy();
214+
215+
Assert.That(dv2.Drives, Has.Count.EqualTo(ValidDrivesCount).And.None.Null);
216+
Assert.That(log.Appender.GetEvents().Length, Is.EqualTo(1));
181217
}
182218
}
183219
}

0 commit comments

Comments
 (0)