Skip to content

Commit 6cf174d

Browse files
David EllingsworthDavid Ellingsworth
David Ellingsworth
authored and
David Ellingsworth
committed
Add tests for GitHub issue #2552
1 parent 56843c7 commit 6cf174d

File tree

4 files changed

+249
-0
lines changed

4 files changed

+249
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace NHibernate.Test.NHSpecificTest.GH2552
2+
{
3+
public abstract class Details
4+
{
5+
public virtual int Id { get; protected set; }
6+
public virtual Person Person { get; set; }
7+
public virtual string Data { get; set; }
8+
}
9+
public class DetailsByFK : Details { }
10+
public class DetailsByRef : Details { }
11+
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
using NHibernate.Cache;
5+
using NHibernate.Stat;
6+
using NHibernate.Test.CacheTest.Caches;
7+
using NUnit.Framework;
8+
using NHCfg = NHibernate.Cfg;
9+
10+
namespace NHibernate.Test.NHSpecificTest.GH2552
11+
{
12+
[TestFixture]
13+
public class Fixture : BugTestCase
14+
{
15+
protected override string CacheConcurrencyStrategy => null;
16+
17+
protected override void Configure(NHCfg.Configuration configuration)
18+
{
19+
configuration.SetProperty(NHCfg.Environment.UseSecondLevelCache, "true");
20+
configuration.SetProperty(NHCfg.Environment.GenerateStatistics, "true");
21+
}
22+
23+
protected override void OnSetUp()
24+
{
25+
// Initialize database with data
26+
using (var s = Sfi.OpenSession())
27+
using (var tx =s.BeginTransaction())
28+
{
29+
for (var i = 0; i < 6; i++)
30+
{
31+
var person = new PersonByFK()
32+
{
33+
Name = $"PersonByFK{i}",
34+
Details = (i % 2 == 0)
35+
? new DetailsByFK() { Data = $"DetailsByFK{i}" }
36+
: null,
37+
};
38+
39+
s.Save(person);
40+
}
41+
42+
for (var i = 0; i < 6; i++)
43+
{
44+
var person = new PersonByRef()
45+
{
46+
Name = $"PersonByRef{i}",
47+
Details = (i % 2 == 1)
48+
? new DetailsByRef() { Data = $"DetailsByRef{i}" }
49+
: null,
50+
};
51+
52+
s.Save(person);
53+
}
54+
55+
tx.Commit();
56+
}
57+
}
58+
59+
protected override void OnTearDown()
60+
{
61+
using (var s = OpenSession())
62+
using (var tx = s.BeginTransaction())
63+
{
64+
s.CreateQuery("delete from DetailsByFK").ExecuteUpdate();
65+
s.CreateQuery("delete from PersonByFK").ExecuteUpdate();
66+
s.CreateQuery("delete from DetailsByRef").ExecuteUpdate();
67+
s.CreateQuery("delete from PersonByRef").ExecuteUpdate();
68+
69+
tx.Commit();
70+
}
71+
72+
Sfi.Evict(typeof(PersonByFK));
73+
Sfi.Evict(typeof(DetailsByFK));
74+
Sfi.Evict(typeof(PersonByRef));
75+
Sfi.Evict(typeof(DetailsByRef));
76+
}
77+
78+
private BatchableCache GetDefaultQueryCache()
79+
{
80+
var queryCache = Sfi.GetQueryCache(null);
81+
var field = typeof(StandardQueryCache).GetField(
82+
"_cache",
83+
BindingFlags.NonPublic | BindingFlags.Instance);
84+
Assert.That(field, Is.Not.Null, "Unable to find _cache field");
85+
var cache = (BatchableCache) field.GetValue(queryCache);
86+
Assert.That(cache, Is.Not.Null, "_cache is null");
87+
88+
return cache;
89+
}
90+
91+
private void OneToOneTest<TPerson, TDetails>() where TPerson : Person, new() where TDetails : Details, new()
92+
{
93+
List<object> ids = this.createPersonAndDetails<TPerson, TDetails>();
94+
95+
IStatistics statistics = Sfi.Statistics;
96+
97+
// Clear the second level cache and the statistics
98+
Sfi.EvictEntity(typeof(TPerson).FullName);
99+
Sfi.EvictEntity(typeof(TDetails).FullName);
100+
Sfi.EvictQueries();
101+
102+
statistics.Clear();
103+
104+
// Fill the empty caches with data.
105+
this.getPersons<TPerson>(ids);
106+
107+
// Verify that no data was retrieved from the cache.
108+
Assert.AreEqual(0, statistics.SecondLevelCacheHitCount, "Second level cache hit count");
109+
110+
statistics.Clear();
111+
112+
this.getPersons<TPerson>(ids);
113+
114+
Assert.AreEqual(0, statistics.SecondLevelCacheMissCount, "Second level cache miss count");
115+
}
116+
117+
private List<object> createPersonAndDetails<TPerson, TDetails>() where TPerson : Person, new() where TDetails : Details, new()
118+
{
119+
List<object> ids = new List<object>();
120+
121+
using (ISession s = Sfi.OpenSession())
122+
using (ITransaction tx = s.BeginTransaction())
123+
{
124+
for (int i = 0; i < 6; i++)
125+
{
126+
Person person = new TPerson();
127+
128+
if (i % 2 == 0)
129+
{
130+
Details details = new TDetails();
131+
132+
details.Data = String.Format("{0}{1}", typeof(TDetails).Name, i);
133+
134+
person.Details = details;
135+
}
136+
137+
person.Name = String.Format("{0}{1}", typeof(TPerson).Name, i);
138+
139+
ids.Add(s.Save(person));
140+
}
141+
142+
tx.Commit();
143+
}
144+
145+
return ids;
146+
}
147+
148+
public IList<TPerson> getPersons<TPerson>(List<object> ids) where TPerson : Person
149+
{
150+
IList<TPerson> people = new List<TPerson>();
151+
152+
using (ISession s = Sfi.OpenSession())
153+
using (ITransaction tx = s.BeginTransaction())
154+
{
155+
foreach (object id in ids)
156+
{
157+
people.Add(s.Get<TPerson>(id));
158+
}
159+
160+
tx.Commit();
161+
}
162+
163+
return people;
164+
}
165+
166+
[Test]
167+
public void OneToOneCacheByForeignKey()
168+
{
169+
OneToOneTest<PersonByFK, DetailsByFK>();
170+
}
171+
172+
[Test]
173+
public void OneToOneCacheByRef()
174+
{
175+
OneToOneTest<PersonByRef, DetailsByRef>();
176+
}
177+
}
178+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.GH2552">
3+
<class name="PersonByFK" batch-size="3">
4+
<cache usage="read-only"/>
5+
<id name="Id" unsaved-value="0" generator="native"/>
6+
<property name="Name"/>
7+
<one-to-one name="Details" class="DetailsByFK" fetch="join" cascade="all"/>
8+
</class>
9+
10+
<class name="DetailsByFK">
11+
<cache usage="read-only"/>
12+
<id name="Id" unsaved-value="0">
13+
<generator class="foreign">
14+
<param name="property">Person</param>
15+
</generator>
16+
</id>
17+
<one-to-one name="Person" class="PersonByFK" constrained="true"/>
18+
<property name="Data"/>
19+
</class>
20+
21+
<class name="PersonByRef" batch-size="3">
22+
<cache usage="read-only"/>
23+
<id name="Id" unsaved-value="0" generator="native"/>
24+
<property name="Name" />
25+
<one-to-one name="Details" class="DetailsByRef" property-ref="Person" fetch="join" cascade="all"/>
26+
</class>
27+
28+
<class name="DetailsByRef">
29+
<cache usage="read-only"/>
30+
<id name="Id" unsaved-value="0" generator="native"/>
31+
<many-to-one name="Person" class="PersonByRef" column="PersonId" unique="true"/>
32+
<property name="Data"/>
33+
</class>
34+
</hibernate-mapping>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace NHibernate.Test.NHSpecificTest.GH2552
2+
{
3+
public abstract class Person
4+
{
5+
private Details _details;
6+
7+
public virtual int Id { get; protected set; }
8+
public virtual string Name { get; set; }
9+
public virtual Details Details {
10+
get => _details;
11+
set
12+
{
13+
_details = value;
14+
15+
if (_details != null)
16+
{
17+
_details.Person = this;
18+
}
19+
}
20+
}
21+
22+
}
23+
public class PersonByFK : Person { }
24+
25+
public class PersonByRef : Person { }
26+
}

0 commit comments

Comments
 (0)