Skip to content

Commit 87623b3

Browse files
Check the test from Jacob Karlén
1 parent e15822d commit 87623b3

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

src/NHibernate.Test/Ado/BatcherFixture.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Linq;
12
using NHibernate.AdoNet;
23
using NHibernate.Cfg;
34
using NUnit.Framework;
@@ -303,5 +304,56 @@ public void AbstractBatcherLogFormattedSql()
303304
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(1));
304305
Cleanup();
305306
}
307+
308+
[Test]
309+
[Description("Inserting exactly BatchSize entities should not throw on commit. See GH-3725.")]
310+
public void InsertExactlyBatchSizeEntitiesShouldNotThrowOnCommit()
311+
{
312+
// This test verifies that DbBatchBatcher handles empty batches correctly.
313+
// The bug (GH-3725): When inserting exactly BatchSize entities, the batch auto-executes
314+
// when full (via ExecuteBatchWithTiming), which clears _currentBatch but NOT _batchCommand.
315+
// On commit, ExecuteBatch() is called, sees _batchCommand is set, and calls DoExecuteBatch
316+
// on an empty _currentBatch, causing InvalidOperationException.
317+
318+
// BatchSize is configured as 10 in this fixture
319+
const int batchSize = 10;
320+
321+
using (var session = OpenSession())
322+
using (var transaction = session.BeginTransaction())
323+
{
324+
// Insert exactly BatchSize entities - this fills the batch and triggers auto-execution
325+
for (int i = 0; i < batchSize; i++)
326+
{
327+
session.Save(new VerySimple { Id = 1000 + i, Name = $"Test{i}", Weight = i * 1.1 });
328+
}
329+
330+
// Commit triggers ExecuteBatch() which would fail on empty batch without the fix
331+
transaction.Commit();
332+
}
333+
334+
Cleanup();
335+
}
336+
337+
[Test]
338+
[Description("Inserting a multiple of BatchSize entities should not throw on commit. See GH-3725.")]
339+
public void InsertMultipleOfBatchSizeEntitiesShouldNotThrowOnCommit()
340+
{
341+
// Same issue as above but with multiple full batches
342+
const int batchSize = 10;
343+
const int multiplier = 3;
344+
345+
using (var session = OpenSession())
346+
using (var transaction = session.BeginTransaction())
347+
{
348+
for (int i = 0; i < batchSize * multiplier; i++)
349+
{
350+
session.Save(new VerySimple { Id = 2000 + i, Name = $"Test{i}", Weight = i * 1.1 });
351+
}
352+
353+
transaction.Commit();
354+
}
355+
356+
Cleanup();
357+
}
306358
}
307359
}

src/NHibernate.Test/Async/Ado/BatcherFixture.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//------------------------------------------------------------------------------
99

1010

11+
using System.Linq;
1112
using NHibernate.AdoNet;
1213
using NHibernate.Cfg;
1314
using NUnit.Framework;
@@ -275,5 +276,56 @@ public async Task AbstractBatcherLogFormattedSqlAsync()
275276
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(1));
276277
await (CleanupAsync());
277278
}
279+
280+
[Test]
281+
[Description("Inserting exactly BatchSize entities should not throw on commit. See GH-3725.")]
282+
public async Task InsertExactlyBatchSizeEntitiesShouldNotThrowOnCommitAsync()
283+
{
284+
// This test verifies that DbBatchBatcher handles empty batches correctly.
285+
// The bug (GH-3725): When inserting exactly BatchSize entities, the batch auto-executes
286+
// when full (via ExecuteBatchWithTiming), which clears _currentBatch but NOT _batchCommand.
287+
// On commit, ExecuteBatch() is called, sees _batchCommand is set, and calls DoExecuteBatch
288+
// on an empty _currentBatch, causing InvalidOperationException.
289+
290+
// BatchSize is configured as 10 in this fixture
291+
const int batchSize = 10;
292+
293+
using (var session = OpenSession())
294+
using (var transaction = session.BeginTransaction())
295+
{
296+
// Insert exactly BatchSize entities - this fills the batch and triggers auto-execution
297+
for (int i = 0; i < batchSize; i++)
298+
{
299+
await (session.SaveAsync(new VerySimple { Id = 1000 + i, Name = $"Test{i}", Weight = i * 1.1 }));
300+
}
301+
302+
// Commit triggers ExecuteBatch() which would fail on empty batch without the fix
303+
await (transaction.CommitAsync());
304+
}
305+
306+
await (CleanupAsync());
307+
}
308+
309+
[Test]
310+
[Description("Inserting a multiple of BatchSize entities should not throw on commit. See GH-3725.")]
311+
public async Task InsertMultipleOfBatchSizeEntitiesShouldNotThrowOnCommitAsync()
312+
{
313+
// Same issue as above but with multiple full batches
314+
const int batchSize = 10;
315+
const int multiplier = 3;
316+
317+
using (var session = OpenSession())
318+
using (var transaction = session.BeginTransaction())
319+
{
320+
for (int i = 0; i < batchSize * multiplier; i++)
321+
{
322+
await (session.SaveAsync(new VerySimple { Id = 2000 + i, Name = $"Test{i}", Weight = i * 1.1 }));
323+
}
324+
325+
await (transaction.CommitAsync());
326+
}
327+
328+
await (CleanupAsync());
329+
}
278330
}
279331
}

0 commit comments

Comments
 (0)