Skip to content

Commit 06bbb63

Browse files
committed
Merge branch 'NH3487' of github.com:JKeyser/nhibernate-core into JKeyser-NH3487
2 parents 71994bd + 8e7a3b9 commit 06bbb63

File tree

6 files changed

+185
-2
lines changed

6 files changed

+185
-2
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using Iesi.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.NH3487
5+
{
6+
[Serializable()]
7+
public class Entity
8+
{
9+
public virtual Key Id { get; set; }
10+
public virtual string Name { get; set; }
11+
12+
public override bool Equals(object obj)
13+
{
14+
if(obj is Entity)
15+
{
16+
var otherEntity = (Entity)obj;
17+
return otherEntity.Id.Equals(this.Id);
18+
}
19+
return false;
20+
}
21+
22+
public override int GetHashCode()
23+
{
24+
return Id.GetHashCode();
25+
}
26+
}
27+
28+
[Serializable()]
29+
public class Key
30+
{
31+
public virtual int Id { get; set; }
32+
33+
public override bool Equals(object obj)
34+
{
35+
if (obj is Key)
36+
{
37+
var otherEntity = (Key)obj;
38+
return otherEntity.Id == this.Id;
39+
}
40+
return false;
41+
}
42+
43+
public override int GetHashCode()
44+
{
45+
// Important to reproduce the problem - forces the keys to collide in the hash map
46+
return 1;
47+
}
48+
}
49+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Linq;
3+
using System.IO;
4+
using System.Runtime.Serialization;
5+
using System.Runtime.Serialization.Formatters.Binary;
6+
using NHibernate.Linq;
7+
using NHibernate.Collection;
8+
using NUnit.Framework;
9+
10+
namespace NHibernate.Test.NHSpecificTest.NH3487
11+
{
12+
[TestFixture]
13+
public class Fixture : BugTestCase
14+
{
15+
private Key key1;
16+
private Key key2;
17+
18+
public override string BugNumber
19+
{
20+
get { return "NH3487"; }
21+
}
22+
23+
protected override void OnSetUp()
24+
{
25+
using (ISession session = OpenSession())
26+
{
27+
using (ITransaction transaction = session.BeginTransaction())
28+
{
29+
key1 = new Key() { Id = 1 };
30+
var entity1 = new Entity { Id = key1, Name = "Bob1" };
31+
session.Save(entity1);
32+
33+
key2 = new Key() { Id = 2 };
34+
var entity2 = new Entity { Id = key2, Name = "Bob2" };
35+
session.Save(entity2);
36+
37+
session.Flush();
38+
transaction.Commit();
39+
}
40+
}
41+
}
42+
43+
protected override void OnTearDown()
44+
{
45+
using (ISession session = OpenSession())
46+
{
47+
using (ITransaction transaction = session.BeginTransaction())
48+
{
49+
session.Delete("from System.Object");
50+
51+
session.Flush();
52+
transaction.Commit();
53+
}
54+
}
55+
}
56+
57+
[Test]
58+
public void Test()
59+
{
60+
IFormatter formatter = new BinaryFormatter();
61+
byte[] serializedSessionArray;
62+
63+
using (ISession session = OpenSession())
64+
{
65+
using (session.BeginTransaction())
66+
{
67+
var entity1 = session.Get<Entity>(key1);
68+
var entity2 = session.Get<Entity>(key2);
69+
}
70+
71+
session.Disconnect();
72+
using (var serializationStream = new MemoryStream())
73+
{
74+
formatter.Serialize(serializationStream, session);
75+
serializationStream.Close();
76+
serializedSessionArray = serializationStream.ToArray();
77+
}
78+
}
79+
80+
ISession deserializedSession;
81+
using (var serializationStream = new MemoryStream(serializedSessionArray))
82+
{
83+
deserializedSession = (ISession)formatter.Deserialize(serializationStream);
84+
}
85+
86+
}
87+
}
88+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.NH3487">
3+
4+
<class name="Entity">
5+
<composite-id name="Id">
6+
<key-property name="Id" />
7+
</composite-id>
8+
<property name="Name" not-null="true" />
9+
</class>
10+
11+
</hibernate-mapping>

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,8 @@
690690
<Compile Include="NHSpecificTest\BagWithLazyExtraAndFilter\Fixture.cs" />
691691
<Compile Include="Linq\ByMethod\DistinctTests.cs" />
692692
<Compile Include="Component\Basic\ComponentWithUniqueConstraintTests.cs" />
693+
<Compile Include="NHSpecificTest\NH3487\Entity.cs" />
694+
<Compile Include="NHSpecificTest\NH3487\Fixture.cs" />
693695
<Compile Include="NHSpecificTest\NH3620\Fixture.cs" />
694696
<Compile Include="NHSpecificTest\NH3620\TwoBlobs.cs" />
695697
<Compile Include="NHSpecificTest\NH3455\Address.cs" />
@@ -3065,6 +3067,7 @@
30653067
<EmbeddedResource Include="Unionsubclass\DatabaseKeyword.hbm.xml" />
30663068
<EmbeddedResource Include="NHSpecificTest\NH1082\Mappings.hbm.xml" />
30673069
<EmbeddedResource Include="NHSpecificTest\NH3571\Mappings.hbm.xml" />
3070+
<EmbeddedResource Include="NHSpecificTest\NH3487\Mappings.hbm.xml" />
30683071
<EmbeddedResource Include="NHSpecificTest\NH2692\Mappings.hbm.xml">
30693072
<SubType>Designer</SubType>
30703073
</EmbeddedResource>

src/NHibernate/Tuple/EntityModeToTuplizerMapping.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Runtime.Serialization;
34
using NHibernate.Util;
45

56
namespace NHibernate.Tuple
67
{
78
/// <summary> Centralizes handling of <see cref="EntityMode"/> to <see cref="ITuplizer"/> mappings. </summary>
89
[Serializable]
9-
public abstract class EntityModeToTuplizerMapping
10+
public abstract class EntityModeToTuplizerMapping : IDeserializationCallback
1011
{
12+
1113
// NH-1660
1214
private readonly IDictionary<EntityMode, ITuplizer> tuplizers
1315
= new LinkedHashMap<EntityMode, ITuplizer>(5, new EntityModeEqualityComparer());
16+
[NonSerialized()]
17+
private bool isFullyDeserialized = false;
18+
19+
public EntityModeToTuplizerMapping()
20+
{
21+
isFullyDeserialized = true;
22+
}
1423

1524
protected internal void AddTuplizer(EntityMode entityMode, ITuplizer tuplizer)
1625
{
26+
EnsureFullyDeserialized();
1727
tuplizers[entityMode] = tuplizer;
1828
}
1929

@@ -22,6 +32,7 @@ protected internal void AddTuplizer(EntityMode entityMode, ITuplizer tuplizer)
2232
/// <returns> The guessed entity mode. </returns>
2333
public virtual EntityMode? GuessEntityMode(object obj)
2434
{
35+
EnsureFullyDeserialized();
2536
foreach (KeyValuePair<EntityMode, ITuplizer> entry in tuplizers)
2637
{
2738
ITuplizer tuplizer = entry.Value;
@@ -41,6 +52,7 @@ protected internal void AddTuplizer(EntityMode entityMode, ITuplizer tuplizer)
4152
/// <returns> The tuplizer, or null if not found. </returns>
4253
public virtual ITuplizer GetTuplizerOrNull(EntityMode entityMode)
4354
{
55+
EnsureFullyDeserialized();
4456
ITuplizer result;
4557
tuplizers.TryGetValue(entityMode, out result);
4658
return result;
@@ -65,5 +77,19 @@ public virtual ITuplizer GetTuplizer(EntityMode entityMode)
6577
}
6678
return tuplizer;
6779
}
80+
81+
private void EnsureFullyDeserialized()
82+
{
83+
if (!isFullyDeserialized)
84+
{
85+
((IDeserializationCallback)this).OnDeserialization(this);
86+
}
87+
}
88+
89+
void IDeserializationCallback.OnDeserialization(object sender)
90+
{
91+
((IDeserializationCallback)tuplizers).OnDeserialization(sender);
92+
isFullyDeserialized = true;
93+
}
6894
}
6995
}

src/NHibernate/Util/LinkedHashMap.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections;
33
using System.Collections.Generic;
44
using System.Diagnostics;
5+
using System.Runtime.Serialization;
56
using System.Text;
67
using NHibernate.DebugHelpers;
78

@@ -18,7 +19,7 @@ namespace NHibernate.Util
1819
/// </remarks>
1920
[DebuggerTypeProxy(typeof(CollectionProxy<>))]
2021
[Serializable]
21-
public class LinkedHashMap<TKey, TValue> : IDictionary<TKey, TValue>
22+
public class LinkedHashMap<TKey, TValue> : IDictionary<TKey, TValue>, IDeserializationCallback
2223
{
2324
[Serializable]
2425
protected class Entry
@@ -359,6 +360,11 @@ private bool RemoveImpl(TKey key)
359360
return result;
360361
}
361362

363+
void IDeserializationCallback.OnDeserialization(object sender)
364+
{
365+
((IDeserializationCallback)entries).OnDeserialization(sender);
366+
}
367+
362368
#region System.Object Members
363369

364370
public override string ToString()

0 commit comments

Comments
 (0)