|
8 | 8 | //------------------------------------------------------------------------------ |
9 | 9 |
|
10 | 10 |
|
| 11 | +using System.Linq; |
11 | 12 | using NHibernate.AdoNet; |
12 | 13 | using NHibernate.Cfg; |
13 | 14 | using NUnit.Framework; |
@@ -275,5 +276,56 @@ public async Task AbstractBatcherLogFormattedSqlAsync() |
275 | 276 | Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(1)); |
276 | 277 | await (CleanupAsync()); |
277 | 278 | } |
| 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 | + } |
278 | 330 | } |
279 | 331 | } |
0 commit comments