Skip to content

Commit cf0f19c

Browse files
committed
NH-3564 - Fix possible second level cache key calculation issue.
1 parent f43ee1c commit cf0f19c

File tree

4 files changed

+177
-2
lines changed

4 files changed

+177
-2
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using NHibernate.Cache;
6+
using NHibernate.Cfg;
7+
using NHibernate.Cfg.MappingSchema;
8+
using NHibernate.Linq;
9+
using NHibernate.Mapping.ByCode;
10+
using NUnit.Framework;
11+
using Environment = NHibernate.Cfg.Environment;
12+
13+
namespace NHibernate.Test.NHSpecificTest.NH3564
14+
{
15+
public class MyDummyCache : ICache
16+
{
17+
private IDictionary hashtable = new Hashtable();
18+
private readonly string regionName;
19+
20+
public MyDummyCache(string regionName)
21+
{
22+
this.regionName = regionName;
23+
}
24+
25+
public object Get(object key)
26+
{
27+
return hashtable[KeyAsString(key)];
28+
}
29+
30+
public void Put(object key, object value)
31+
{
32+
hashtable[KeyAsString(key)] = value;
33+
}
34+
35+
public void Remove(object key)
36+
{
37+
hashtable.Remove(KeyAsString(key));
38+
}
39+
40+
public void Clear()
41+
{
42+
hashtable.Clear();
43+
}
44+
45+
public void Destroy()
46+
{
47+
}
48+
49+
public void Lock(object key)
50+
{
51+
// local cache, so we use synchronization
52+
}
53+
54+
public void Unlock(object key)
55+
{
56+
// local cache, so we use synchronization
57+
}
58+
59+
public long NextTimestamp()
60+
{
61+
return Timestamper.Next();
62+
}
63+
64+
public int Timeout
65+
{
66+
get { return Timestamper.OneMs*60000; }
67+
}
68+
69+
public string RegionName
70+
{
71+
get { return regionName; }
72+
}
73+
74+
private string KeyAsString(object key)
75+
{
76+
//This is how MemCached provider uses key.
77+
return string.Format("{0}@{1}", RegionName, (key == null ? string.Empty : key.ToString()));
78+
}
79+
}
80+
81+
public class MyDummyCacheProvider : ICacheProvider
82+
{
83+
public ICache BuildCache(string regionName, IDictionary<string, string> properties)
84+
{
85+
return new MyDummyCache(regionName);
86+
}
87+
88+
public long NextTimestamp()
89+
{
90+
return Timestamper.Next();
91+
}
92+
93+
public void Start(IDictionary<string, string> properties)
94+
{
95+
}
96+
97+
public void Stop()
98+
{
99+
}
100+
}
101+
102+
class Person
103+
{
104+
public virtual Guid Id { get; set; }
105+
public virtual string Name { get; set; }
106+
public virtual DateTime DateOfBirth { get; set; }
107+
}
108+
109+
public class FixtureByCode : TestCaseMappingByCode
110+
{
111+
protected override HbmMapping GetMappings()
112+
{
113+
var mapper = new ModelMapper();
114+
mapper.Class<Person>(rc =>
115+
{
116+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
117+
rc.Property(x => x.Name);
118+
rc.Property(x => x.DateOfBirth, pm =>
119+
{
120+
pm.Type(NHibernateUtil.Timestamp);
121+
});
122+
});
123+
124+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
125+
}
126+
127+
protected override void Configure(Configuration configuration)
128+
{
129+
configuration.SetProperty(Environment.CacheProvider, typeof (MyDummyCacheProvider).AssemblyQualifiedName);
130+
configuration.SetProperty(Environment.UseQueryCache, "true");
131+
}
132+
133+
protected override void OnSetUp()
134+
{
135+
using (var session = OpenSession())
136+
using (var transaction = session.BeginTransaction())
137+
{
138+
session.Save(new Person {Name = "Bob", DateOfBirth = new DateTime(2015, 4, 22)});
139+
session.Save(new Person {Name = "Sally", DateOfBirth = new DateTime(2014, 4, 22)});
140+
141+
transaction.Commit();
142+
}
143+
}
144+
145+
protected override void OnTearDown()
146+
{
147+
using (var session = OpenSession())
148+
using (var transaction = session.BeginTransaction())
149+
{
150+
session.Delete("from System.Object");
151+
152+
session.Flush();
153+
transaction.Commit();
154+
}
155+
}
156+
157+
[Test]
158+
public void ShouldUseDifferentCache()
159+
{
160+
using (var session = OpenSession())
161+
using (session.BeginTransaction())
162+
{
163+
var bob = session.Query<Person>().Cacheable().Where(e => e.DateOfBirth == new DateTime(2015, 4, 22)).ToList();
164+
var sally = session.Query<Person>().Cacheable().Where(e => e.DateOfBirth == new DateTime(2014, 4, 22)).ToList();
165+
166+
Assert.That(bob, Has.Count.EqualTo(1));
167+
Assert.That(bob[0].Name, Is.EqualTo("Bob"));
168+
169+
Assert.That(sally, Has.Count.EqualTo(1));
170+
Assert.That(sally[0].Name, Is.EqualTo("Sally"));
171+
}
172+
}
173+
}
174+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@
717717
<Compile Include="NHSpecificTest\BagWithLazyExtraAndFilter\Fixture.cs" />
718718
<Compile Include="Linq\ByMethod\DistinctTests.cs" />
719719
<Compile Include="Component\Basic\ComponentWithUniqueConstraintTests.cs" />
720+
<Compile Include="NHSpecificTest\NH3564\FixtureByCode.cs" />
720721
<Compile Include="NHSpecificTest\NH3583\Entity.cs" />
721722
<Compile Include="NHSpecificTest\NH3583\AutoFlushFixture.cs" />
722723
<Compile Include="NHSpecificTest\NH3372\Entity.cs" />

src/NHibernate/Type/TimeType.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public override int GetHashCode(object x, EntityMode entityMode)
105105

106106
public override string ToString(object val)
107107
{
108-
return ((DateTime) val).ToShortTimeString();
108+
return ((DateTime) val).ToString("T");
109109
}
110110

111111
public object StringToObject(string xml)

src/NHibernate/Type/TimestampType.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public override string Name
7070

7171
public override string ToString(object val)
7272
{
73-
return ((DateTime) val).ToShortTimeString();
73+
return ((DateTime) val).ToString("O");
7474
}
7575

7676
public override object FromStringValue(string xml)

0 commit comments

Comments
 (0)