From 4460dba56103a115c8edbb456f75d827b3fc9874 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Tue, 11 May 2021 02:14:20 +1200 Subject: [PATCH 1/3] Change cascade style for DefaultDirtyCheckEventListener to persist on flush 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 delyed until flush is called. Fixes #1413 --- .../Async/NHSpecificTest/GH1413/FixtureByCode.cs | 7 +++---- src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs | 7 +++---- .../Async/Event/Default/DefaultDirtyCheckEventListener.cs | 2 ++ .../Event/Default/DefaultDirtyCheckEventListener.cs | 6 ++++++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs index d9e228b4c95..336ae4c9234 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs @@ -74,13 +74,12 @@ protected override void OnTearDown() } } - [Test] - [KnownBug("#1413")] - public async Task SessionIsDirtyShouldNotTriggerCascadeSavingAsync() + [Theory] + public async Task SessionIsDirtyShouldNotTriggerCascadeSavingAsync(bool beginTransaction) { Sfi.Statistics.IsStatisticsEnabled = true; using (var session = OpenSession()) - using (session.BeginTransaction()) + using (beginTransaction ? session.BeginTransaction() : null) { var parent = await (GetParentAsync(session)); var entityChild = new EntityChild diff --git a/src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs index 9668a232da9..cbda4a8aabc 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs @@ -62,13 +62,12 @@ protected override void OnTearDown() } } - [Test] - [KnownBug("#1413")] - public void SessionIsDirtyShouldNotTriggerCascadeSaving() + [Theory] + public void SessionIsDirtyShouldNotTriggerCascadeSaving(bool beginTransaction) { Sfi.Statistics.IsStatisticsEnabled = true; using (var session = OpenSession()) - using (session.BeginTransaction()) + using (beginTransaction ? session.BeginTransaction() : null) { var parent = GetParent(session); var entityChild = new EntityChild diff --git a/src/NHibernate/Async/Event/Default/DefaultDirtyCheckEventListener.cs b/src/NHibernate/Async/Event/Default/DefaultDirtyCheckEventListener.cs index f4b47a26a9c..a161d50366a 100644 --- a/src/NHibernate/Async/Event/Default/DefaultDirtyCheckEventListener.cs +++ b/src/NHibernate/Async/Event/Default/DefaultDirtyCheckEventListener.cs @@ -9,6 +9,8 @@ using System; +using NHibernate.Engine; +using NHibernate.Util; namespace NHibernate.Event.Default { diff --git a/src/NHibernate/Event/Default/DefaultDirtyCheckEventListener.cs b/src/NHibernate/Event/Default/DefaultDirtyCheckEventListener.cs index e8692a1f0bd..9c346dbb0e2 100644 --- a/src/NHibernate/Event/Default/DefaultDirtyCheckEventListener.cs +++ b/src/NHibernate/Event/Default/DefaultDirtyCheckEventListener.cs @@ -1,4 +1,6 @@ using System; +using NHibernate.Engine; +using NHibernate.Util; namespace NHibernate.Event.Default { @@ -11,6 +13,10 @@ public partial class DefaultDirtyCheckEventListener : AbstractFlushingEventListe { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(DefaultDirtyCheckEventListener)); + protected override object Anything => IdentityMap.Instantiate(10); + + protected override CascadingAction CascadingAction => CascadingAction.Persist; + public virtual void OnDirtyCheck(DirtyCheckEvent @event) { int oldSize = @event.Session.ActionQueue.CollectionRemovalsCount; From b495ef3f4fa532706839ef1ad664e9b25e461ca8 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Tue, 11 May 2021 10:10:45 +1200 Subject: [PATCH 2/3] Fix tests for dialects not supporting identity columns --- .../Async/NHSpecificTest/GH1413/FixtureByCode.cs | 12 ++++++++---- .../NHSpecificTest/GH1413/FixtureByCode.cs | 16 ++++++++++------ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs index 336ae4c9234..f7493d99301 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs @@ -9,6 +9,7 @@ using NHibernate.Cfg.MappingSchema; +using NHibernate.Engine; using NHibernate.Mapping.ByCode; using NUnit.Framework; @@ -94,11 +95,14 @@ public async Task SessionIsDirtyShouldNotTriggerCascadeSavingAsync(bool beginTra var isDirty = await (session.IsDirtyAsync()); Assert.That(Sfi.Statistics.EntityInsertCount, Is.EqualTo(0), "Dirty has triggered an insert"); - Assert.That( - entityChild.Id, - Is.EqualTo(0), - "Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)"); Assert.That(isDirty, "ISession.IsDirty() call should return true."); + if (Dialect.SupportsIdentityColumns) + { + Assert.That( + entityChild.Id, + Is.EqualTo(0), + "Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)"); + } } } diff --git a/src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs index cbda4a8aabc..c487a7ebbb9 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH1413/FixtureByCode.cs @@ -1,4 +1,5 @@ using NHibernate.Cfg.MappingSchema; +using NHibernate.Engine; using NHibernate.Mapping.ByCode; using NUnit.Framework; @@ -14,7 +15,7 @@ protected override HbmMapping GetMappings() var mapper = new ModelMapper(); mapper.Class(rc => { - rc.Id(x => x.Id, m => m.Generator(Generators.Native)); + rc.Id(x => x.Id, m => m.Generator(Generators.Identity)); rc.Property(x => x.Name); rc.Bag(x => x.Children, m => { @@ -26,7 +27,7 @@ protected override HbmMapping GetMappings() mapper.Class(rc => { - rc.Id(x => x.Id, m => m.Generator(Generators.Native)); + rc.Id(x => x.Id, m => m.Generator(Generators.Identity)); rc.Property(x => x.Name); }); @@ -82,11 +83,14 @@ public void SessionIsDirtyShouldNotTriggerCascadeSaving(bool beginTransaction) var isDirty = session.IsDirty(); Assert.That(Sfi.Statistics.EntityInsertCount, Is.EqualTo(0), "Dirty has triggered an insert"); - Assert.That( - entityChild.Id, - Is.EqualTo(0), - "Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)"); Assert.That(isDirty, "ISession.IsDirty() call should return true."); + if (Dialect.SupportsIdentityColumns) + { + Assert.That( + entityChild.Id, + Is.EqualTo(0), + "Transient objects should not be saved by ISession.IsDirty() call (expected 0 as Id)"); + } } } From 08e9340a5a76b07b6d01b183f1e932f45d3e39de Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Tue, 11 May 2021 22:13:09 +1200 Subject: [PATCH 3/3] Regenerate async --- .../Async/NHSpecificTest/GH1413/FixtureByCode.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs index f7493d99301..712cc7a54d9 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH1413/FixtureByCode.cs @@ -27,7 +27,7 @@ protected override HbmMapping GetMappings() var mapper = new ModelMapper(); mapper.Class(rc => { - rc.Id(x => x.Id, m => m.Generator(Generators.Native)); + rc.Id(x => x.Id, m => m.Generator(Generators.Identity)); rc.Property(x => x.Name); rc.Bag(x => x.Children, m => { @@ -39,7 +39,7 @@ protected override HbmMapping GetMappings() mapper.Class(rc => { - rc.Id(x => x.Id, m => m.Generator(Generators.Native)); + rc.Id(x => x.Id, m => m.Generator(Generators.Identity)); rc.Property(x => x.Name); });