Skip to content

Commit 89a79d2

Browse files
authored
Change cascade style for DefaultDirtyCheckEventListener to persist to avoid flushing the session (#2752)
The default cascade for it was SaveUpdate (via base AbstractFlushingEventListener) which triggered insertion of the entities with post-insert style ID generators (eg. identity). Persist on the other hand will make sure that insertion of the entity is delayed until flush is called. Related to #1413
1 parent 0b05e8f commit 89a79d2

File tree

4 files changed

+34
-20
lines changed

4 files changed

+34
-20
lines changed

src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs

+13-10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010

1111
using NHibernate.Cfg.MappingSchema;
12+
using NHibernate.Engine;
1213
using NHibernate.Mapping.ByCode;
1314
using NUnit.Framework;
1415

@@ -26,7 +27,7 @@ protected override HbmMapping GetMappings()
2627
var mapper = new ModelMapper();
2728
mapper.Class<EntityParent>(rc =>
2829
{
29-
rc.Id(x => x.Id, m => m.Generator(Generators.Native));
30+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
3031
rc.Property(x => x.Name);
3132
rc.Bag(x => x.Children, m =>
3233
{
@@ -38,7 +39,7 @@ protected override HbmMapping GetMappings()
3839

3940
mapper.Class<EntityChild>(rc =>
4041
{
41-
rc.Id(x => x.Id, m => m.Generator(Generators.Native));
42+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
4243
rc.Property(x => x.Name);
4344
});
4445

@@ -74,13 +75,12 @@ protected override void OnTearDown()
7475
}
7576
}
7677

77-
[Test]
78-
[KnownBug("#1413")]
79-
public async Task SessionIsDirtyShouldNotTriggerCascadeSavingAsync()
78+
[Theory]
79+
public async Task SessionIsDirtyShouldNotTriggerCascadeSavingAsync(bool beginTransaction)
8080
{
8181
Sfi.Statistics.IsStatisticsEnabled = true;
8282
using (var session = OpenSession())
83-
using (session.BeginTransaction())
83+
using (beginTransaction ? session.BeginTransaction() : null)
8484
{
8585
var parent = await (GetParentAsync(session));
8686
var entityChild = new EntityChild
@@ -95,11 +95,14 @@ public async Task SessionIsDirtyShouldNotTriggerCascadeSavingAsync()
9595
var isDirty = await (session.IsDirtyAsync());
9696

9797
Assert.That(Sfi.Statistics.EntityInsertCount, Is.EqualTo(0), "Dirty has triggered an insert");
98-
Assert.That(
99-
entityChild.Id,
100-
Is.EqualTo(0),
101-
"Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)");
10298
Assert.That(isDirty, "ISession.IsDirty() call should return true.");
99+
if (Dialect.SupportsIdentityColumns)
100+
{
101+
Assert.That(
102+
entityChild.Id,
103+
Is.EqualTo(0),
104+
"Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)");
105+
}
103106
}
104107
}
105108

src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using NHibernate.Cfg.MappingSchema;
2+
using NHibernate.Engine;
23
using NHibernate.Mapping.ByCode;
34
using NUnit.Framework;
45

@@ -14,7 +15,7 @@ protected override HbmMapping GetMappings()
1415
var mapper = new ModelMapper();
1516
mapper.Class<EntityParent>(rc =>
1617
{
17-
rc.Id(x => x.Id, m => m.Generator(Generators.Native));
18+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
1819
rc.Property(x => x.Name);
1920
rc.Bag(x => x.Children, m =>
2021
{
@@ -26,7 +27,7 @@ protected override HbmMapping GetMappings()
2627

2728
mapper.Class<EntityChild>(rc =>
2829
{
29-
rc.Id(x => x.Id, m => m.Generator(Generators.Native));
30+
rc.Id(x => x.Id, m => m.Generator(Generators.Identity));
3031
rc.Property(x => x.Name);
3132
});
3233

@@ -62,13 +63,12 @@ protected override void OnTearDown()
6263
}
6364
}
6465

65-
[Test]
66-
[KnownBug("#1413")]
67-
public void SessionIsDirtyShouldNotTriggerCascadeSaving()
66+
[Theory]
67+
public void SessionIsDirtyShouldNotTriggerCascadeSaving(bool beginTransaction)
6868
{
6969
Sfi.Statistics.IsStatisticsEnabled = true;
7070
using (var session = OpenSession())
71-
using (session.BeginTransaction())
71+
using (beginTransaction ? session.BeginTransaction() : null)
7272
{
7373
var parent = GetParent(session);
7474
var entityChild = new EntityChild
@@ -83,11 +83,14 @@ public void SessionIsDirtyShouldNotTriggerCascadeSaving()
8383
var isDirty = session.IsDirty();
8484

8585
Assert.That(Sfi.Statistics.EntityInsertCount, Is.EqualTo(0), "Dirty has triggered an insert");
86-
Assert.That(
87-
entityChild.Id,
88-
Is.EqualTo(0),
89-
"Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)");
9086
Assert.That(isDirty, "ISession.IsDirty() call should return true.");
87+
if (Dialect.SupportsIdentityColumns)
88+
{
89+
Assert.That(
90+
entityChild.Id,
91+
Is.EqualTo(0),
92+
"Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)");
93+
}
9194
}
9295
}
9396

src/NHibernate/Async/Event/Default/DefaultDirtyCheckEventListener.cs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010

1111
using System;
12+
using NHibernate.Engine;
13+
using NHibernate.Util;
1214

1315
namespace NHibernate.Event.Default
1416
{

src/NHibernate/Event/Default/DefaultDirtyCheckEventListener.cs

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using NHibernate.Engine;
3+
using NHibernate.Util;
24

35
namespace NHibernate.Event.Default
46
{
@@ -11,6 +13,10 @@ public partial class DefaultDirtyCheckEventListener : AbstractFlushingEventListe
1113
{
1214
private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(DefaultDirtyCheckEventListener));
1315

16+
protected override object Anything => IdentityMap.Instantiate(10);
17+
18+
protected override CascadingAction CascadingAction => CascadingAction.Persist;
19+
1420
public virtual void OnDirtyCheck(DirtyCheckEvent @event)
1521
{
1622
int oldSize = @event.Session.ActionQueue.CollectionRemovalsCount;

0 commit comments

Comments
 (0)