Skip to content

Commit 3ab267c

Browse files
committed
Fix base type for interface proxies
1 parent 21846c0 commit 3ab267c

File tree

3 files changed

+188
-1
lines changed

3 files changed

+188
-1
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.GH2067
4+
{
5+
public interface ICat
6+
{
7+
Guid Id { get; set; }
8+
string Name { get; set; }
9+
}
10+
11+
public class Cat : ICat
12+
{
13+
public virtual Guid Id { get; set; }
14+
public virtual string Name { get; set; }
15+
}
16+
17+
public interface IPet
18+
{
19+
string OwnerName { get; set; }
20+
}
21+
22+
public interface IDomesticCat : IPet, ICat
23+
{
24+
}
25+
26+
public sealed class DomesticCat : Cat, IDomesticCat
27+
{
28+
public string OwnerName { get; set; }
29+
}
30+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
using System;
2+
using NHibernate.Cfg.MappingSchema;
3+
using NHibernate.Mapping.ByCode;
4+
using NUnit.Framework;
5+
6+
namespace NHibernate.Test.NHSpecificTest.GH2067
7+
{
8+
[TestFixture]
9+
public class Fixture : TestCaseMappingByCode
10+
{
11+
private object domesticCatId;
12+
private object catId;
13+
14+
protected override HbmMapping GetMappings()
15+
{
16+
var mapper = new ModelMapper();
17+
mapper.Class<Cat>(rc =>
18+
{
19+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
20+
rc.Property(x => x.Name);
21+
});
22+
23+
mapper.JoinedSubclass<DomesticCat>(rc =>
24+
{
25+
rc.Proxy(typeof(IDomesticCat));
26+
rc.Property(x => x.OwnerName);
27+
});
28+
29+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
30+
}
31+
32+
protected override void OnSetUp()
33+
{
34+
using (var session = OpenSession())
35+
using (var transaction = session.BeginTransaction())
36+
{
37+
catId = session.Save(new Cat { Name = "Bob" });
38+
39+
domesticCatId = session.Save(new DomesticCat {Name = "Tom", OwnerName = "Jerry"});
40+
41+
transaction.Commit();
42+
}
43+
}
44+
45+
protected override void OnTearDown()
46+
{
47+
using (var session = OpenSession())
48+
using (var transaction = session.BeginTransaction())
49+
{
50+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
51+
52+
transaction.Commit();
53+
}
54+
}
55+
56+
[Test]
57+
public void CanLoadDomesticCatUsingBaseClass()
58+
{
59+
using (var session = OpenSession())
60+
using (session.BeginTransaction())
61+
{
62+
var cat = session.Load<Cat>(domesticCatId);
63+
Assert.That(cat, Is.Not.Null);
64+
}
65+
}
66+
67+
[Test]
68+
public void CanLoadDomesticCatUsingBaseClassInterface()
69+
{
70+
using (var session = OpenSession())
71+
using (session.BeginTransaction())
72+
{
73+
var cat = session.Load<ICat>(domesticCatId);
74+
Assert.That(cat, Is.Not.Null);
75+
}
76+
}
77+
78+
[Test]
79+
public void CanLoadDomesticCatUsingInterface()
80+
{
81+
using (var session = OpenSession())
82+
using (session.BeginTransaction())
83+
{
84+
var cat = session.Load<IDomesticCat>(domesticCatId);
85+
Assert.That(cat, Is.Not.Null);
86+
}
87+
}
88+
89+
[Test]
90+
public void ThrowWhenTryToLoadDomesticCatUsingSealedClass()
91+
{
92+
using (var session = OpenSession())
93+
using (session.BeginTransaction())
94+
{
95+
Assert.Throws<InvalidCastException>(() => session.Load<DomesticCat>(domesticCatId));
96+
}
97+
}
98+
99+
[Test]
100+
public void CanLoadDomesticCatUsingSealedClass()
101+
{
102+
using (var session = OpenSession())
103+
using (session.BeginTransaction())
104+
{
105+
var cat = (IDomesticCat) session.Load(typeof(DomesticCat), domesticCatId);
106+
Assert.That(cat, Is.Not.Null);
107+
}
108+
}
109+
110+
[Test]
111+
public void CanLoadDomesticCatUsingSideInterface()
112+
{
113+
using (var session = OpenSession())
114+
using (session.BeginTransaction())
115+
{
116+
var cat = session.Load<IPet>(domesticCatId);
117+
Assert.That(cat, Is.Not.Null);
118+
}
119+
}
120+
121+
[Test]
122+
public void CanLoadCatUsingClass()
123+
{
124+
using (var session = OpenSession())
125+
using (session.BeginTransaction())
126+
{
127+
var cat = session.Load<Cat>(catId);
128+
Assert.That(cat, Is.Not.Null);
129+
}
130+
}
131+
132+
[Test]
133+
public void CanLoadCatUsingInterface()
134+
{
135+
using (var session = OpenSession())
136+
using (session.BeginTransaction())
137+
{
138+
var cat = session.Load<ICat>(catId);
139+
Assert.That(cat, Is.Not.Null);
140+
}
141+
}
142+
}
143+
}

src/NHibernate/Proxy/StaticProxyFactory.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,21 @@ public override void PostInstantiate(
5454
GetIdentifierMethod,
5555
SetIdentifierMethod,
5656
ComponentIdType);
57-
_cacheEntry = new ProxyCacheEntry(IsClassProxy ? PersistentClass : typeof(object), Interfaces);
57+
_cacheEntry = new ProxyCacheEntry(GetProxyBaseType(PersistentClass), Interfaces);
58+
}
59+
60+
private static System.Type GetProxyBaseType(System.Type type)
61+
{
62+
if (type.IsClass)
63+
{
64+
for (var t = type; t != null; t = t.BaseType)
65+
{
66+
if (!t.IsSealed)
67+
return t;
68+
}
69+
}
70+
71+
return typeof(object);
5872
}
5973

6074
private Func<ILazyInitializer, NHibernateProxyFactoryInfo, INHibernateProxy> CreateProxyActivator(ProxyCacheEntry pke)

0 commit comments

Comments
 (0)