Skip to content

Commit 0d96cdc

Browse files
committed
PersistentGenericSet: Avoid comparing values of possibly a primitive type with null, to fix NH-3590.
1 parent bd74e34 commit 0d96cdc

File tree

4 files changed

+34
-25
lines changed

4 files changed

+34
-25
lines changed

src/NHibernate.Test/NHSpecificTest/NH3590/Fixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ protected override void OnSetUp()
2222
}
2323
}
2424

25-
[Test, KnownBug("3590")]
25+
[Test]
2626
public void ShouldUpdate()
2727
{
2828
entity.Dates.Add(DateTime.Now);
@@ -45,7 +45,7 @@ public void ShouldUpdate()
4545
}
4646
}
4747

48-
[Test, KnownBug("3590")]
48+
[Test]
4949
public void ShouldMerge()
5050
{
5151
entity.Dates.Add(DateTime.Now);

src/NHibernate/Collection/Generic/PersistentGenericSet.cs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,15 @@ public override bool EqualsSnapshot(ICollectionPersister persister)
109109
return false;
110110
}
111111

112-
return !(from object obj in WrappedSet
113-
let oldValue = snapshot[(T)obj]
114-
where oldValue == null || elementType.IsDirty(oldValue, obj, Session)
115-
select obj).Any();
112+
113+
foreach (T obj in WrappedSet)
114+
{
115+
T oldValue;
116+
if (!snapshot.TryGetValue(obj, out oldValue) || elementType.IsDirty(oldValue, obj, Session))
117+
return false;
118+
}
119+
120+
return true;
116121
}
117122

118123
public override bool IsSnapshotEmpty(object snapshot)
@@ -138,10 +143,10 @@ public override void InitializeFromCache(ICollectionPersister persister, object
138143
BeforeInitialize(persister, size);
139144
for (int i = 0; i < size; i++)
140145
{
141-
var element = (T)persister.ElementType.Assemble(array[i], Session, owner);
146+
var element = persister.ElementType.Assemble(array[i], Session, owner);
142147
if (element != null)
143148
{
144-
WrappedSet.Add(element);
149+
WrappedSet.Add((T) element);
145150
}
146151
}
147152
SetInitialized();
@@ -160,10 +165,10 @@ public override string ToString()
160165

161166
public override object ReadFrom(IDataReader rs, ICollectionPersister role, ICollectionAliases descriptor, object owner)
162167
{
163-
var element = (T)role.ReadElement(rs, owner, descriptor.SuffixedElementAliases, Session);
168+
var element = role.ReadElement(rs, owner, descriptor.SuffixedElementAliases, Session);
164169
if (element != null)
165170
{
166-
_tempList.Add(element);
171+
_tempList.Add((T) element);
167172
}
168173
return element;
169174
}
@@ -219,22 +224,26 @@ public override IEnumerable GetDeletes(ICollectionPersister persister, bool inde
219224

220225
deletes.AddRange(sn.Where(obj => !WrappedSet.Contains(obj)));
221226

222-
deletes.AddRange(from obj in WrappedSet
223-
let oldValue = sn[obj]
224-
where oldValue != null && elementType.IsDirty(obj, oldValue, Session)
225-
select oldValue);
227+
228+
foreach (var obj in WrappedSet)
229+
{
230+
T oldValue;
231+
if (sn.TryGetValue(obj, out oldValue) && elementType.IsDirty(obj, oldValue, Session))
232+
deletes.Add(oldValue);
233+
}
226234

227235
return deletes;
228236
}
229237

230238
public override bool NeedsInserting(object entry, int i, IType elemType)
231239
{
232240
var sn = (ISetSnapshot<T>)GetSnapshot();
233-
object oldKey = sn[(T)entry];
241+
T oldKey;
242+
234243
// note that it might be better to iterate the snapshot but this is safe,
235244
// assuming the user implements equals() properly, as required by the PersistentSet
236245
// contract!
237-
return oldKey == null || elemType.IsDirty(oldKey, entry, Session);
246+
return !sn.TryGetValue((T) entry, out oldKey) || elemType.IsDirty(oldKey, entry, Session);
238247
}
239248

240249
public override bool NeedsUpdating(object entry, int i, IType elemType)

src/NHibernate/Collection/Generic/SetHelpers/ISetSnapshot.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ namespace NHibernate.Collection.Generic.SetHelpers
55
{
66
internal interface ISetSnapshot<T> : ICollection<T>, ICollection
77
{
8-
T this[T element] { get; }
8+
bool TryGetValue(T element, out T value);
99
}
1010
}

src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,17 @@ public bool IsReadOnly
8888
get { return ((ICollection<T>)_elements).IsReadOnly; }
8989
}
9090

91-
public T this[T element]
91+
public bool TryGetValue(T element, out T value)
9292
{
93-
get
93+
var idx = _elements.IndexOf(element);
94+
if (idx >= 0)
9495
{
95-
var idx = _elements.IndexOf(element);
96-
if (idx >= 0)
97-
{
98-
return _elements[idx];
99-
}
100-
return default(T);
96+
value = _elements[idx];
97+
return true;
10198
}
99+
100+
value = default(T);
101+
return false;
102102
}
103103
}
104104
}

0 commit comments

Comments
 (0)