Skip to content

Commit e2e6cbe

Browse files
authored
Fix fetching lazy component on not mapped interface (#3320)
Fixes #3289
1 parent 8cb65c8 commit e2e6cbe

File tree

4 files changed

+258
-0
lines changed

4 files changed

+258
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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.Linq;
12+
using NHibernate.Cfg.MappingSchema;
13+
using NHibernate.Linq;
14+
using NHibernate.Mapping.ByCode;
15+
using NUnit.Framework;
16+
17+
namespace NHibernate.Test.NHSpecificTest.GH3289
18+
{
19+
using System.Threading.Tasks;
20+
[TestFixture]
21+
public class ByCodeFixtureAsync : TestCaseMappingByCode
22+
{
23+
protected override HbmMapping GetMappings()
24+
{
25+
var mapper = new ModelMapper();
26+
mapper.Class<Entity>(rc =>
27+
{
28+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
29+
rc.Property(x => x.Name);
30+
rc.Component(x => x.Component);
31+
});
32+
mapper.Class<OtherEntity>(rc =>
33+
{
34+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
35+
rc.Property(x => x.Name);
36+
rc.Component(x => x.Component);
37+
});
38+
mapper.JoinedSubclass<SubEntity>(rc =>
39+
{
40+
rc.Key(k => k.Column("Id"));
41+
rc.Property(x => x.SomeProperty);
42+
});
43+
mapper.Component<Component>(rc =>
44+
{
45+
rc.Property(x => x.Field);
46+
rc.Lazy(true);
47+
});
48+
49+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
50+
}
51+
52+
protected override void OnSetUp()
53+
{
54+
using var session = OpenSession();
55+
using var transaction = session.BeginTransaction();
56+
var e1 = new SubEntity { Name = "Jim" };
57+
session.Save(e1);
58+
59+
transaction.Commit();
60+
}
61+
62+
protected override void OnTearDown()
63+
{
64+
using var session = OpenSession();
65+
using var transaction = session.BeginTransaction();
66+
67+
if (Dialect.SupportsTemporaryTables)
68+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
69+
else
70+
session.Delete("from System.Object");
71+
72+
transaction.Commit();
73+
}
74+
75+
[Test]
76+
public async Task TestSubEntityInterfaceWithFetchIsPropertyInitializedAsync()
77+
{
78+
using var session = OpenSession();
79+
var data = await (session.Query<ISubEntity>()
80+
.Fetch(e => e.Component)
81+
.ToListAsync());
82+
var result = NHibernateUtil.IsPropertyInitialized(data[0], "Component");
83+
84+
Assert.That(result, Is.True);
85+
}
86+
87+
[Test]
88+
public async Task TestEntityInterfaceWithFetchIsPropertyInitializedAsync()
89+
{
90+
using var session = OpenSession();
91+
var data = await (session.Query<IEntity>()
92+
.Fetch(e => e.Component)
93+
.ToListAsync());
94+
var result = NHibernateUtil.IsPropertyInitialized(data[0], "Component");
95+
96+
Assert.That(result, Is.True);
97+
}
98+
99+
[Test]
100+
public async Task TestSubEntityWithFetchIsPropertyInitializedAsync()
101+
{
102+
using var session = OpenSession();
103+
var data = await (session.Query<SubEntity>()
104+
.Fetch(e => e.Component)
105+
.ToListAsync());
106+
var result = NHibernateUtil.IsPropertyInitialized(data[0], "Component");
107+
108+
Assert.That(result, Is.True);
109+
}
110+
}
111+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System.Linq;
2+
using NHibernate.Cfg.MappingSchema;
3+
using NHibernate.Linq;
4+
using NHibernate.Mapping.ByCode;
5+
using NUnit.Framework;
6+
7+
namespace NHibernate.Test.NHSpecificTest.GH3289
8+
{
9+
[TestFixture]
10+
public class ByCodeFixture : TestCaseMappingByCode
11+
{
12+
protected override HbmMapping GetMappings()
13+
{
14+
var mapper = new ModelMapper();
15+
mapper.Class<Entity>(rc =>
16+
{
17+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
18+
rc.Property(x => x.Name);
19+
rc.Component(x => x.Component);
20+
});
21+
mapper.Class<OtherEntity>(rc =>
22+
{
23+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
24+
rc.Property(x => x.Name);
25+
rc.Component(x => x.Component);
26+
});
27+
mapper.JoinedSubclass<SubEntity>(rc =>
28+
{
29+
rc.Key(k => k.Column("Id"));
30+
rc.Property(x => x.SomeProperty);
31+
});
32+
mapper.Component<Component>(rc =>
33+
{
34+
rc.Property(x => x.Field);
35+
rc.Lazy(true);
36+
});
37+
38+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
39+
}
40+
41+
protected override void OnSetUp()
42+
{
43+
using var session = OpenSession();
44+
using var transaction = session.BeginTransaction();
45+
var e1 = new SubEntity { Name = "Jim" };
46+
session.Save(e1);
47+
48+
transaction.Commit();
49+
}
50+
51+
protected override void OnTearDown()
52+
{
53+
using var session = OpenSession();
54+
using var transaction = session.BeginTransaction();
55+
56+
if (Dialect.SupportsTemporaryTables)
57+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
58+
else
59+
session.Delete("from System.Object");
60+
61+
transaction.Commit();
62+
}
63+
64+
[Test]
65+
public void TestSubEntityInterfaceWithFetchIsPropertyInitialized()
66+
{
67+
using var session = OpenSession();
68+
var data = session.Query<ISubEntity>()
69+
.Fetch(e => e.Component)
70+
.ToList();
71+
var result = NHibernateUtil.IsPropertyInitialized(data[0], "Component");
72+
73+
Assert.That(result, Is.True);
74+
}
75+
76+
[Test]
77+
public void TestEntityInterfaceWithFetchIsPropertyInitialized()
78+
{
79+
using var session = OpenSession();
80+
var data = session.Query<IEntity>()
81+
.Fetch(e => e.Component)
82+
.ToList();
83+
var result = NHibernateUtil.IsPropertyInitialized(data[0], "Component");
84+
85+
Assert.That(result, Is.True);
86+
}
87+
88+
[Test]
89+
public void TestSubEntityWithFetchIsPropertyInitialized()
90+
{
91+
using var session = OpenSession();
92+
var data = session.Query<SubEntity>()
93+
.Fetch(e => e.Component)
94+
.ToList();
95+
var result = NHibernateUtil.IsPropertyInitialized(data[0], "Component");
96+
97+
Assert.That(result, Is.True);
98+
}
99+
}
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace NHibernate.Test.NHSpecificTest.GH3289
2+
{
3+
public interface IEntity
4+
{
5+
int Id { get; set; }
6+
string Name { get; set; }
7+
Component Component { get; set; }
8+
}
9+
10+
public interface ISubEntity : IEntity
11+
{
12+
public bool SomeProperty { get; set; }
13+
}
14+
15+
public class Entity : IEntity
16+
{
17+
public virtual int Id { get; set; }
18+
public virtual string Name { get; set; }
19+
public virtual Component Component { get; set; }
20+
}
21+
public class OtherEntity : IEntity
22+
{
23+
public virtual int Id { get; set; }
24+
public virtual string Name { get; set; }
25+
public virtual Component Component { get; set; }
26+
}
27+
28+
public class SubEntity : Entity, ISubEntity
29+
{
30+
public virtual bool SomeProperty { get; set; }
31+
}
32+
33+
public class Component
34+
{
35+
public virtual string Field { get; set; }
36+
}
37+
}

src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFetch.cs

+10
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ private void Process(
5252
{
5353
var metadata = queryModelVisitor.VisitorParameters.SessionFactory
5454
.GetClassMetadata(resultOperator.RelationMember.ReflectedType);
55+
if (metadata == null)
56+
{
57+
var entityName = queryModelVisitor.VisitorParameters.SessionFactory.GetImplementors(
58+
resultOperator.RelationMember.ReflectedType.FullName).FirstOrDefault();
59+
if (!string.IsNullOrEmpty(entityName))
60+
{
61+
metadata = queryModelVisitor.VisitorParameters.SessionFactory.GetClassMetadata(entityName);
62+
}
63+
}
64+
5565
propType = metadata?.GetPropertyType(resultOperator.RelationMember.Name);
5666
}
5767

0 commit comments

Comments
 (0)