From 3f916500c26aed0ceac70a050ddbebcc9aeeaba8 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Wed, 8 May 2024 16:43:55 +1000 Subject: [PATCH] Fix CheckInverseList without property comparer to call invalid overload (#688) Closes #212 +semver:fix --- .../UnidirectionalOneToManyTester.cs | 74 +++++++++++++++++++ .../PersistenceSpecificationExtensions.cs | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/FluentNHibernate.Testing/DomainModel/UnidirectionalOneToManyTester.cs diff --git a/src/FluentNHibernate.Testing/DomainModel/UnidirectionalOneToManyTester.cs b/src/FluentNHibernate.Testing/DomainModel/UnidirectionalOneToManyTester.cs new file mode 100644 index 000000000..f3811fee0 --- /dev/null +++ b/src/FluentNHibernate.Testing/DomainModel/UnidirectionalOneToManyTester.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using FluentNHibernate.Mapping; +using FluentNHibernate.Testing.Cfg; +using NUnit.Framework; + +namespace FluentNHibernate.Testing.DomainModel; + +public class UnidirectionalOneToManyTester +{ + [SetUp] + public void SetUp() + { + var properties = SQLiteFrameworkConfigurationFactory + .CreateStandardConfiguration() + .UseOuterJoin() + .ShowSql() + .InMemory() + .ToProperties(); + + var model = new PersistenceModel(); + model.Add(typeof(OrderMap)); + model.Add(typeof(LineItemMap)); + _source = new SingleConnectionSessionSourceForSQLiteInMemoryTesting(properties, model); + _source.BuildSchema(); + } + + ISessionSource _source; + + [Test] + public void ShouldHandleUnidirectionalCollections() + { + var order = new Order() { LineItems = new List() }; + order.LineItems.Add(new LineItem()); + new PersistenceSpecification(_source) + /* NHibernate.PropertyValueException: not-null property references + * a null or transient value LineItem._Order.LineItemsBackref */ + .CheckInverseList(o => o.LineItems, order.LineItems, i => i.Id) + .VerifyTheMappings(); + } +} + +public class Order +{ + public virtual Guid Id { get; set; } + public virtual ICollection LineItems { get; set; } +} + +public class LineItem +{ + public virtual Guid Id { get; set; } +} + +public class OrderMap : ClassMap +{ + public OrderMap() + { + Id(x => x.Id).GeneratedBy.GuidComb(); + HasMany(x => x.LineItems) + .Not.Inverse() + .Not.KeyNullable() + .Not.KeyUpdate() + .Cascade.AllDeleteOrphan(); + } +} + +public class LineItemMap : ClassMap +{ + public LineItemMap() + { + Id(x => x.Id).GeneratedBy.GuidComb(); + } +} + diff --git a/src/FluentNHibernate/Testing/PersistenceSpecificationExtensions.cs b/src/FluentNHibernate/Testing/PersistenceSpecificationExtensions.cs index 14d474018..ddf82b343 100644 --- a/src/FluentNHibernate/Testing/PersistenceSpecificationExtensions.cs +++ b/src/FluentNHibernate/Testing/PersistenceSpecificationExtensions.cs @@ -166,7 +166,7 @@ public static PersistenceSpecification CheckInverseList(this // Because of the params keyword, the compiler can select this overload // instead of the one above, even when no funcs are supplied in the method call. if (propertiesToCompare is null || propertiesToCompare.Length == 0) - return spec.CheckList(expression, propertyValue, (IEqualityComparer)null); + return spec.CheckInverseList(expression, propertyValue, (IEqualityComparer)null); return spec.CheckInverseList(expression, propertyValue, new FuncEqualityComparer(propertiesToCompare)); }