Skip to content

Commit 8cb65c8

Browse files
authored
Fix components list lazy loading with not lazy associations (nhibernate#3321)
Fixes nhibernate#3317
1 parent 86d463a commit 8cb65c8

File tree

4 files changed

+266
-0
lines changed

4 files changed

+266
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
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.Linq;
13+
using NHibernate.Cfg.MappingSchema;
14+
using NHibernate.Mapping.ByCode;
15+
using NHibernate.Linq;
16+
using NUnit.Framework;
17+
18+
namespace NHibernate.Test.NHSpecificTest.GH3317
19+
{
20+
using System.Threading.Tasks;
21+
[TestFixture(true)]
22+
[TestFixture(false)]
23+
public class ComponentsListFixtureAsync : TestCaseMappingByCode
24+
{
25+
private readonly bool _fetchJoinMapping;
26+
private Guid _id;
27+
28+
public ComponentsListFixtureAsync(bool fetchJoinMapping)
29+
{
30+
_fetchJoinMapping = fetchJoinMapping;
31+
}
32+
33+
protected override void OnSetUp()
34+
{
35+
using var session = OpenSession();
36+
using var tr = session.BeginTransaction();
37+
var root = new Entity();
38+
root.Entries.Add(new ComponentListEntry { ComponentReference = null, DummyString = "one", });
39+
40+
session.Save(root);
41+
tr.Commit();
42+
_id = root.Id;
43+
}
44+
45+
[Test]
46+
public async Task LazyLoadingAsync()
47+
{
48+
using var newSession = OpenSession();
49+
var reloadedRoot = await (newSession.GetAsync<Entity>(_id));
50+
Assert.AreEqual(1, reloadedRoot.Entries.Count);
51+
}
52+
53+
[Test]
54+
public async Task QueryOverFetchAsync()
55+
{
56+
using var newSession = OpenSession();
57+
var reloadedRoot = await (newSession.QueryOver<Entity>()
58+
.Fetch(SelectMode.Fetch, x => x.Entries)
59+
.Where(x => x.Id == _id)
60+
.SingleOrDefaultAsync());
61+
Assert.AreEqual(1, reloadedRoot.Entries.Count);
62+
}
63+
64+
[Test]
65+
public async Task LinqFetchAsync()
66+
{
67+
using var newSession = OpenSession();
68+
var reloadedRoot = await (newSession.Query<Entity>()
69+
.Fetch(x => x.Entries)
70+
.Where(x => x.Id == _id)
71+
.SingleOrDefaultAsync());
72+
Assert.AreEqual(1, reloadedRoot.Entries.Count);
73+
}
74+
75+
protected override void OnTearDown()
76+
{
77+
using var session = OpenSession();
78+
using var transaction = session.BeginTransaction();
79+
session.CreateSQLQuery("delete from Entries").ExecuteUpdate();
80+
session.Delete("from System.Object");
81+
transaction.Commit();
82+
}
83+
84+
protected override HbmMapping GetMappings()
85+
{
86+
var mapper = new ModelMapper();
87+
88+
mapper.Class<Entity>(rc =>
89+
{
90+
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
91+
rc.Lazy(false);
92+
rc.Property(x => x.Name);
93+
94+
rc.Bag(
95+
x => x.Entries,
96+
v =>
97+
{
98+
if (_fetchJoinMapping)
99+
v.Fetch(CollectionFetchMode.Join);
100+
},
101+
h => h.Component(cmp =>
102+
{
103+
cmp.Property(x => x.DummyString);
104+
cmp.ManyToOne(x => x.ComponentReference);
105+
}));
106+
});
107+
mapper.Class<EntityWithParent>(rc =>
108+
{
109+
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
110+
rc.Lazy(false);
111+
rc.ManyToOne(x => x.Parent, m => m.NotNullable(true));
112+
});
113+
mapper.Class<ParentEntity>(rc =>
114+
{
115+
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
116+
rc.Lazy(false);
117+
rc.Property(x => x.Name);
118+
});
119+
120+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
121+
}
122+
}
123+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH3317
5+
{
6+
public class Entity
7+
{
8+
public Guid Id { get; set; }
9+
public string Name { get; set; }
10+
public IList<ComponentListEntry> Entries { get; set; } = new List<ComponentListEntry>();
11+
}
12+
13+
public class ComponentListEntry
14+
{
15+
public string DummyString { get; set; }
16+
public EntityWithParent ComponentReference { get; set; }
17+
}
18+
19+
public class EntityWithParent
20+
{
21+
public Guid Id { get; set; }
22+
public ParentEntity Parent { get; set; }
23+
}
24+
25+
public class ParentEntity
26+
{
27+
public Guid Id { get; set; }
28+
public string Name { get; set; }
29+
}
30+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using System;
2+
using System.Linq;
3+
using NHibernate.Cfg.MappingSchema;
4+
using NHibernate.Mapping.ByCode;
5+
using NHibernate.Linq;
6+
using NUnit.Framework;
7+
8+
namespace NHibernate.Test.NHSpecificTest.GH3317
9+
{
10+
[TestFixture(true)]
11+
[TestFixture(false)]
12+
public class ComponentsListFixture : TestCaseMappingByCode
13+
{
14+
private readonly bool _fetchJoinMapping;
15+
private Guid _id;
16+
17+
public ComponentsListFixture(bool fetchJoinMapping)
18+
{
19+
_fetchJoinMapping = fetchJoinMapping;
20+
}
21+
22+
protected override void OnSetUp()
23+
{
24+
using var session = OpenSession();
25+
using var tr = session.BeginTransaction();
26+
var root = new Entity();
27+
root.Entries.Add(new ComponentListEntry { ComponentReference = null, DummyString = "one", });
28+
29+
session.Save(root);
30+
tr.Commit();
31+
_id = root.Id;
32+
}
33+
34+
[Test]
35+
public void LazyLoading()
36+
{
37+
using var newSession = OpenSession();
38+
var reloadedRoot = newSession.Get<Entity>(_id);
39+
Assert.AreEqual(1, reloadedRoot.Entries.Count);
40+
}
41+
42+
[Test]
43+
public void QueryOverFetch()
44+
{
45+
using var newSession = OpenSession();
46+
var reloadedRoot = newSession.QueryOver<Entity>()
47+
.Fetch(SelectMode.Fetch, x => x.Entries)
48+
.Where(x => x.Id == _id)
49+
.SingleOrDefault();
50+
Assert.AreEqual(1, reloadedRoot.Entries.Count);
51+
}
52+
53+
[Test]
54+
public void LinqFetch()
55+
{
56+
using var newSession = OpenSession();
57+
var reloadedRoot = newSession.Query<Entity>()
58+
.Fetch(x => x.Entries)
59+
.Where(x => x.Id == _id)
60+
.SingleOrDefault();
61+
Assert.AreEqual(1, reloadedRoot.Entries.Count);
62+
}
63+
64+
protected override void OnTearDown()
65+
{
66+
using var session = OpenSession();
67+
using var transaction = session.BeginTransaction();
68+
session.CreateSQLQuery("delete from Entries").ExecuteUpdate();
69+
session.Delete("from System.Object");
70+
transaction.Commit();
71+
}
72+
73+
protected override HbmMapping GetMappings()
74+
{
75+
var mapper = new ModelMapper();
76+
77+
mapper.Class<Entity>(rc =>
78+
{
79+
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
80+
rc.Lazy(false);
81+
rc.Property(x => x.Name);
82+
83+
rc.Bag(
84+
x => x.Entries,
85+
v =>
86+
{
87+
if (_fetchJoinMapping)
88+
v.Fetch(CollectionFetchMode.Join);
89+
},
90+
h => h.Component(cmp =>
91+
{
92+
cmp.Property(x => x.DummyString);
93+
cmp.ManyToOne(x => x.ComponentReference);
94+
}));
95+
});
96+
mapper.Class<EntityWithParent>(rc =>
97+
{
98+
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
99+
rc.Lazy(false);
100+
rc.ManyToOne(x => x.Parent, m => m.NotNullable(true));
101+
});
102+
mapper.Class<ParentEntity>(rc =>
103+
{
104+
rc.Id(x => x.Id, map => map.Generator(Generators.GuidComb));
105+
rc.Lazy(false);
106+
rc.Property(x => x.Name);
107+
});
108+
109+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
110+
}
111+
}
112+
}

src/NHibernate/Loader/JoinWalker.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ private void WalkCollectionTree(IQueryableCollection persister, string alias, st
375375
}
376376
else if (type.IsComponentType)
377377
{
378+
_joinQueue.Enqueue(NextLevelJoinQueueEntry.Instance);
378379
WalkCompositeElementTree(
379380
(IAbstractComponentType) type,
380381
persister.ElementColumnNames,

0 commit comments

Comments
 (0)