Skip to content

Commit d354e9e

Browse files
SecondLevel QueryCache causes invalid cast (nhibernate#1489)
* Fix nhibernate#1385 * Promote ResultType to a Loader member: * Cease passing around ResultTypes while concrete implementations do all store it as a member. * Simplifies this fix. * Not implemented as an abstract to override for avoiding a breaking change.
1 parent 2de124a commit d354e9e

20 files changed

+693
-381
lines changed

src/NHibernate.Test/Async/CacheTest/QueryCacheFixture.cs

+53-23
Original file line numberDiff line numberDiff line change
@@ -8,68 +8,98 @@
88
//------------------------------------------------------------------------------
99

1010

11-
using System;
1211
using System.Collections;
1312
using NHibernate.Cfg;
1413
using NHibernate.DomainModel;
1514
using NUnit.Framework;
16-
using Environment=NHibernate.Cfg.Environment;
15+
using Environment = NHibernate.Cfg.Environment;
1716

1817
namespace NHibernate.Test.CacheTest
1918
{
2019
using System.Threading.Tasks;
2120
[TestFixture]
2221
public class QueryCacheFixtureAsync : TestCase
2322
{
24-
protected override IList Mappings
23+
protected override IList Mappings => new[] { "Simple.hbm.xml" };
24+
25+
protected override void Configure(Configuration configuration)
2526
{
26-
get { return new string[] {"Simple.hbm.xml"}; }
27+
configuration.SetProperty(Environment.UseQueryCache, "true");
2728
}
2829

29-
protected override void Configure(Configuration cfg)
30+
protected override void OnSetUp()
3031
{
31-
cfg.SetProperty(Environment.UseQueryCache, "true");
32+
using (var s = OpenSession())
33+
{
34+
s.Save(new Simple(), 1L);
35+
s.Flush();
36+
}
3237
}
3338

34-
[Test]
35-
public async Task QueryCacheWithNullParametersAsync()
39+
protected override void OnTearDown()
3640
{
37-
Simple simple = new Simple();
38-
39-
using (ISession s = OpenSession())
41+
using (var s = OpenSession())
4042
{
41-
await (s.SaveAsync(simple, 1L));
42-
await (s.FlushAsync());
43+
s.Delete("from Simple");
44+
s.Flush();
4345
}
46+
}
4447

45-
using (ISession s = OpenSession())
48+
[Test]
49+
public async Task QueryCacheWithNullParametersAsync()
50+
{
51+
using (var s = OpenSession())
4652
{
53+
const string query = "from Simple s where s = :s or s.Name = :name or s.Address = :address";
4754
await (s
48-
.CreateQuery("from Simple s where s = :s or s.Name = :name or s.Address = :address")
55+
.CreateQuery(query)
4956
.SetEntity("s", await (s.LoadAsync(typeof(Simple), 1L)))
5057
.SetString("name", null)
5158
.SetString("address", null)
5259
.SetCacheable(true)
5360
.UniqueResultAsync());
5461

5562
// Run a second time, just to test the query cache
56-
object result = await (s
57-
.CreateQuery("from Simple s where s = :s or s.Name = :name or s.Address = :address")
63+
var result = await (s
64+
.CreateQuery(query)
5865
.SetEntity("s", await (s.LoadAsync(typeof(Simple), 1L)))
5966
.SetString("name", null)
6067
.SetString("address", null)
6168
.SetCacheable(true)
6269
.UniqueResultAsync());
6370

64-
Assert.IsNotNull(result);
65-
Assert.AreEqual(1L, (long) s.GetIdentifier(result));
71+
Assert.That(result, Is.Not.Null);
72+
Assert.That(s.GetIdentifier(result), Is.EqualTo(1));
6673
}
74+
}
6775

68-
using (ISession s = OpenSession())
76+
[Test]
77+
public async Task QueryCacheWithScalarReturnAsync()
78+
{
79+
// Using decimal because:
80+
// - int is yielded back as decimal by Oracle, wrecking the cast back to int.
81+
// - Oracle requires a cast to binary_double for yielding a double instead of decimal.
82+
// - double is not castable in MySql.
83+
// So long for SQLite which does not have a true decimal type.
84+
if (TestDialect.HasBrokenDecimalType)
85+
Assert.Ignore("Database does not support properly decimals.");
86+
87+
using (var s = OpenSession())
6988
{
70-
await (s.DeleteAsync("from Simple"));
71-
await (s.FlushAsync());
89+
var result = await (s
90+
.CreateSQLQuery("select cast(200012 as decimal) from Simple where id_ = 1")
91+
.SetCacheable(true)
92+
.UniqueResultAsync<decimal>());
93+
94+
Assert.That(result, Is.EqualTo(200012), "Unexpected non-cached result");
95+
96+
result = await (s
97+
.CreateSQLQuery("select cast(200012 as decimal) from Simple where id_ = 1")
98+
.SetCacheable(true)
99+
.UniqueResultAsync<decimal>());
100+
101+
Assert.That(result, Is.EqualTo(200012), "Unexpected cached result");
72102
}
73103
}
74104
}
75-
}
105+
}

0 commit comments

Comments
 (0)