Skip to content

Commit 3009d23

Browse files
committed
Changes according to second review
1 parent c514bb9 commit 3009d23

17 files changed

+82
-336
lines changed

src/NHibernate.Test/Async/Extralazy/ExtraLazyFixture.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,7 +2049,7 @@ public async Task MapSetAsync(bool initialize)
20492049
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(1), "Statements count after load");
20502050
Assert.That(NHibernateUtil.IsInitialized(gavin.Settings), Is.False, "User settings initialization status after load");
20512051

2052-
// Set a key that does not exist in db and it is not in the queue
2052+
// Set a key that does not exist in db and is not in the queue
20532053
Sfi.Statistics.Clear();
20542054
for (var i = 0; i < 5; i++)
20552055
{
@@ -2075,7 +2075,7 @@ public async Task MapSetAsync(bool initialize)
20752075
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(0), "Statements count after re-adding existing keys");
20762076
Assert.That(NHibernateUtil.IsInitialized(gavin.Settings), Is.False, "User settings initialization status after re-adding existing keys");
20772077

2078-
// Set a key that exists in db and it is not in the queue
2078+
// Set a key that exists in db and is not in the queue
20792079
Sfi.Statistics.Clear();
20802080
gavin.Settings["s0"] = new UserSetting("s0", "s0", gavin);
20812081

@@ -2172,7 +2172,7 @@ public async Task MapRemoveAsync(bool initialize)
21722172
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(5), "Statements count after adding");
21732173
Assert.That(NHibernateUtil.IsInitialized(gavin.Settings), Is.False, "User settings initialization status after adding");
21742174

2175-
// Remove a key that exists in db and it is not in the queue and removal queue
2175+
// Remove a key that exists in db and is not in the queue and removal queue
21762176
Sfi.Statistics.Clear();
21772177
Assert.That(gavin.Settings.Remove("s0"), Is.True, "Removing an existing element");
21782178

@@ -2193,7 +2193,7 @@ public async Task MapRemoveAsync(bool initialize)
21932193
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(0), "Statements count after removing a re-added element");
21942194
Assert.That(NHibernateUtil.IsInitialized(gavin.Settings), Is.False, "User settings initialization status after removing a re-added element");
21952195

2196-
// Remove a key that does not exist in db and it is not in the queue
2196+
// Remove a key that does not exist in db and is not in the queue
21972197
Sfi.Statistics.Clear();
21982198
Assert.That(gavin.Settings.Remove("test"), Is.False, "Removing not existing element");
21992199

src/NHibernate.Test/Extralazy/ExtraLazyFixture.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,7 +2038,7 @@ public void MapSet(bool initialize)
20382038
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(1), "Statements count after load");
20392039
Assert.That(NHibernateUtil.IsInitialized(gavin.Settings), Is.False, "User settings initialization status after load");
20402040

2041-
// Set a key that does not exist in db and it is not in the queue
2041+
// Set a key that does not exist in db and is not in the queue
20422042
Sfi.Statistics.Clear();
20432043
for (var i = 0; i < 5; i++)
20442044
{
@@ -2064,7 +2064,7 @@ public void MapSet(bool initialize)
20642064
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(0), "Statements count after re-adding existing keys");
20652065
Assert.That(NHibernateUtil.IsInitialized(gavin.Settings), Is.False, "User settings initialization status after re-adding existing keys");
20662066

2067-
// Set a key that exists in db and it is not in the queue
2067+
// Set a key that exists in db and is not in the queue
20682068
Sfi.Statistics.Clear();
20692069
gavin.Settings["s0"] = new UserSetting("s0", "s0", gavin);
20702070

@@ -2161,7 +2161,7 @@ public void MapRemove(bool initialize)
21612161
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(5), "Statements count after adding");
21622162
Assert.That(NHibernateUtil.IsInitialized(gavin.Settings), Is.False, "User settings initialization status after adding");
21632163

2164-
// Remove a key that exists in db and it is not in the queue and removal queue
2164+
// Remove a key that exists in db and is not in the queue and removal queue
21652165
Sfi.Statistics.Clear();
21662166
Assert.That(gavin.Settings.Remove("s0"), Is.True, "Removing an existing element");
21672167

@@ -2182,7 +2182,7 @@ public void MapRemove(bool initialize)
21822182
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(0), "Statements count after removing a re-added element");
21832183
Assert.That(NHibernateUtil.IsInitialized(gavin.Settings), Is.False, "User settings initialization status after removing a re-added element");
21842184

2185-
// Remove a key that does not exist in db and it is not in the queue
2185+
// Remove a key that does not exist in db and is not in the queue
21862186
Sfi.Statistics.Clear();
21872187
Assert.That(gavin.Settings.Remove("test"), Is.False, "Removing not existing element");
21882188

src/NHibernate/Collection/AbstractPersistentCollection.cs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ protected virtual bool ReadSize()
307307
return true;
308308
}
309309

310-
if (!queueOperationTracker.Cleared && queueOperationTracker.DatabaseCollectionSize < 0)
310+
if (!queueOperationTracker.Cleared && !queueOperationTracker.DatabaseCollectionSize.HasValue)
311311
{
312312
queueOperationTracker.DatabaseCollectionSize = persister.GetSize(entry.LoadedKey, session);
313313
}
@@ -517,12 +517,6 @@ protected virtual object ReadElementByIndex(object index)
517517
existsInDb = null;
518518
return false;
519519
}
520-
521-
if (queueOperationTracker.TryGetDatabaseElementByKey(elementKey, out element))
522-
{
523-
existsInDb = true;
524-
return true;
525-
}
526520
}
527521

528522
var elementByKey = persister.GetElementByIndex(entry.LoadedKey, elementKey, session, owner);
@@ -570,7 +564,7 @@ protected virtual object ReadElementByIndex(object index)
570564
}
571565
else
572566
{
573-
if (queueOperationTracker.DatabaseCollectionSize < 0 &&
567+
if (!queueOperationTracker.DatabaseCollectionSize.HasValue &&
574568
queueOperationTracker.RequiresDatabaseCollectionSize(nameof(queueOperationTracker.TryGetElementAtIndex)) &&
575569
!ReadSize())
576570
{
@@ -589,12 +583,14 @@ protected virtual object ReadElementByIndex(object index)
589583
}
590584

591585
// We have to calculate the database index based on the changes in the queue
592-
index = queueOperationTracker.CalculateDatabaseElementIndex(index);
593-
if (index < 0)
586+
var dbIndex = queueOperationTracker.GetDatabaseElementIndex(index);
587+
if (!dbIndex.HasValue)
594588
{
595589
element = default(T);
596590
return false;
597591
}
592+
593+
index = dbIndex.Value;
598594
}
599595
}
600596

@@ -746,7 +742,7 @@ private AbstractQueueOperationTracker TryFlushAndGetQueueOperationTracker(string
746742
}
747743

748744
queueOperationTracker.BeforeOperation(operationName);
749-
if (queueOperationTracker.DatabaseCollectionSize < 0 && queueOperationTracker.RequiresDatabaseCollectionSize(operationName) && !ReadSize())
745+
if (!queueOperationTracker.DatabaseCollectionSize.HasValue && queueOperationTracker.RequiresDatabaseCollectionSize(operationName) && !ReadSize())
750746
{
751747
throw new InvalidOperationException($"The collection role {Role} must be mapped as extra lazy.");
752748
}

src/NHibernate/Collection/Generic/PersistentGenericBag.cs

Lines changed: 3 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,7 @@ int IList.Add(object value)
140140
}
141141

142142
var val = (T) value;
143-
var queueOperationTracker = GetOrCreateQueueOperationTracker();
144-
if (queueOperationTracker != null)
145-
{
146-
QueueAddElement(val);
147-
}
148-
else
149-
{
150-
#pragma warning disable 618
151-
QueueOperation(new SimpleAddDelayedOperation(this, val));
152-
#pragma warning restore 618
153-
}
143+
QueueAddElement(val);
154144

155145
return CachedSize;
156146
}
@@ -206,35 +196,15 @@ public void Add(T item)
206196
}
207197
else
208198
{
209-
var queueOperationTracker = GetOrCreateQueueOperationTracker();
210-
if (queueOperationTracker != null)
211-
{
212-
QueueAddElement(item);
213-
}
214-
else
215-
{
216-
#pragma warning disable 618
217-
QueueOperation(new SimpleAddDelayedOperation(this, item));
218-
#pragma warning restore 618
219-
}
199+
QueueAddElement(item);
220200
}
221201
}
222202

223203
public void Clear()
224204
{
225205
if (ClearQueueEnabled)
226206
{
227-
var queueOperationTracker = GetOrCreateQueueOperationTracker();
228-
if (queueOperationTracker != null)
229-
{
230-
QueueClearCollection();
231-
}
232-
else
233-
{
234-
#pragma warning disable 618
235-
QueueOperation(new ClearDelayedOperation(this));
236-
#pragma warning restore 618
237-
}
207+
QueueClearCollection();
238208
}
239209
else
240210
{
@@ -545,82 +515,5 @@ private static int CountOccurrences(object element, IEnumerable list, IType elem
545515

546516
return result;
547517
}
548-
549-
// Since v5.3
550-
[Obsolete("This class has no more usages in NHibernate and will be removed in a future version.")]
551-
private sealed class ClearDelayedOperation : IDelayedOperation
552-
{
553-
private readonly PersistentGenericBag<T> _enclosingInstance;
554-
555-
public ClearDelayedOperation(PersistentGenericBag<T> enclosingInstance)
556-
{
557-
_enclosingInstance = enclosingInstance;
558-
}
559-
560-
public object AddedInstance
561-
{
562-
get { return null; }
563-
}
564-
565-
public object Orphan
566-
{
567-
get { throw new NotSupportedException("queued clear cannot be used with orphan delete"); }
568-
}
569-
570-
public void Operate()
571-
{
572-
_enclosingInstance._gbag.Clear();
573-
}
574-
}
575-
576-
// Since v5.3
577-
[Obsolete("This class has no more usages in NHibernate and will be removed in a future version.")]
578-
private sealed class SimpleAddDelayedOperation : IDelayedOperation
579-
{
580-
private readonly PersistentGenericBag<T> _enclosingInstance;
581-
private readonly T _value;
582-
583-
public SimpleAddDelayedOperation(PersistentGenericBag<T> enclosingInstance, T value)
584-
{
585-
_enclosingInstance = enclosingInstance;
586-
_value = value;
587-
}
588-
589-
public object AddedInstance
590-
{
591-
get { return _value; }
592-
}
593-
594-
public object Orphan
595-
{
596-
get { return null; }
597-
}
598-
599-
public void Operate()
600-
{
601-
// NH Different behavior for NH-739. A "bag" mapped as a bidirectional one-to-many of an entity with an
602-
// id generator causing it to be inserted on flush must not replay the addition after initialization,
603-
// if the entity was previously saved. In that case, the entity save has inserted it in database with
604-
// its association to the bag, without causing a full flush. So for the bag, the operation is still
605-
// pending, but in database it is already done. On initialization, the bag thus already receives the
606-
// entity in its loaded list, and it should not be added again.
607-
// Since a one-to-many bag is actually a set, we can simply check if the entity is already in the loaded
608-
// state, and discard it if yes. (It also relies on the bag not having pending removes, which is the
609-
// case, since it only handles delayed additions and clears.)
610-
// Since this condition happens with transient instances added in the bag then saved, ReferenceEquals
611-
// is enough to match them.
612-
// This solution is a workaround, the root cause is not fixed. The root cause is the insertion on save
613-
// done without caring for pending operations of one-to-many collections. This root cause could be fixed
614-
// by triggering a full flush there before the insert (currently it just flushes pending inserts), or
615-
// maybe by flushing just the dirty one-to-many non-initialized collections (but this can be tricky).
616-
// (It is also likely one-to-many lists have a similar issue, but nothing is done yet for them. And
617-
// their case is more complex due to having to care for the indexes and to handle many more delayed
618-
// operation kinds.)
619-
if (_enclosingInstance._isOneToMany && _enclosingInstance._gbag.Any(l => ReferenceEquals(l, _value)))
620-
return;
621-
622-
_enclosingInstance._gbag.Add(_value);
623-
}
624-
}
625518
}
626519
}

0 commit comments

Comments
 (0)