From d71f8cc591d53aed86d67ffac6475295df0c86bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Tue, 19 Jun 2018 19:16:32 +0200 Subject: [PATCH] Support formula on one-to-many map-key Fix a null reference exception in OneToManyPersister Spotted while testing #1759 --- .../GH1760/MapKeyFormulaFixture.cs | 83 +++++++++++++++++++ .../NHSpecificTest/GH1760/Domain.cs | 19 +++++ .../GH1760/MapKeyFormulaFixture.cs | 71 ++++++++++++++++ .../NHSpecificTest/GH1760/Mappings.hbm.xml | 24 ++++++ .../Collection/OneToManyPersister.cs | 2 +- 5 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH1760/Domain.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH1760/Mappings.hbm.xml diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs new file mode 100644 index 00000000000..2234a7a5b89 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using NHibernate.Linq; + +namespace NHibernate.Test.NHSpecificTest.GH1760 +{ + using System.Threading.Tasks; + [TestFixture] + public class MapKeyFormulasFixtureAsync : BugTestCase + { + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var bob = + new User + { + Name = "Bob" + }; + session.Save(bob); + + var sally = + new User + { + Name = "Sally" + }; + session.Save(sally); + + var g1 = new Group { Name = "Salesperson" }; + session.Save(g1); + + g1.UsersByName.Add(bob.Name, bob); + g1.UsersByName.Add(sally.Name, sally); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // HQL "delete from" does not handle foreign key order. + session.Delete("from User"); + session.CreateQuery("delete System.Object").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public async Task CheckMapKeyAsync() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var salesperson = await (session.Query().SingleAsync(u => u.Name == "Salesperson")); + + Assert.That( + salesperson.UsersByName, + Has.Count.EqualTo(2) + .And.One.Property(nameof(KeyValuePair.Key)).EqualTo("Bob") + .And.One.Property(nameof(KeyValuePair.Key)).EqualTo("Sally")); + + await (tx.CommitAsync()); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH1760/Domain.cs b/src/NHibernate.Test/NHSpecificTest/GH1760/Domain.cs new file mode 100644 index 00000000000..576bc9c7900 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH1760/Domain.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.GH1760 +{ + class User + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + } + + class Group + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + + public virtual IDictionary UsersByName { get; set; } = new Dictionary(); + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs b/src/NHibernate.Test/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs new file mode 100644 index 00000000000..9b7d9a828a3 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH1760/MapKeyFormulaFixture.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH1760 +{ + [TestFixture] + public class MapKeyFormulasFixture : BugTestCase + { + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var bob = + new User + { + Name = "Bob" + }; + session.Save(bob); + + var sally = + new User + { + Name = "Sally" + }; + session.Save(sally); + + var g1 = new Group { Name = "Salesperson" }; + session.Save(g1); + + g1.UsersByName.Add(bob.Name, bob); + g1.UsersByName.Add(sally.Name, sally); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // HQL "delete from" does not handle foreign key order. + session.Delete("from User"); + session.CreateQuery("delete System.Object").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public void CheckMapKey() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var salesperson = session.Query().Single(u => u.Name == "Salesperson"); + + Assert.That( + salesperson.UsersByName, + Has.Count.EqualTo(2) + .And.One.Property(nameof(KeyValuePair.Key)).EqualTo("Bob") + .And.One.Property(nameof(KeyValuePair.Key)).EqualTo("Sally")); + + tx.Commit(); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH1760/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH1760/Mappings.hbm.xml new file mode 100644 index 00000000000..309cf3b759c --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH1760/Mappings.hbm.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + Name + + + + + + diff --git a/src/NHibernate/Persister/Collection/OneToManyPersister.cs b/src/NHibernate/Persister/Collection/OneToManyPersister.cs index f87b2e60199..f88e1bd2bdf 100644 --- a/src/NHibernate/Persister/Collection/OneToManyPersister.cs +++ b/src/NHibernate/Persister/Collection/OneToManyPersister.cs @@ -76,7 +76,7 @@ protected override SqlCommandInfo GenerateDeleteString() update.SetJoin(ownerPersister.TableName, KeyColumnNames, KeyType, JoinColumnNames, ownerPersister.GetPropertyColumnNames(CollectionType.LHSPropertyName)); } - if (HasIndex) + if (HasIndex && !indexContainsFormula) update.AddColumns(IndexColumnNames, "null"); if (HasWhere)