From 169b0d4469aed40ed18abecaead2c87f36738bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Thu, 11 May 2023 06:53:18 +0200 Subject: [PATCH 1/6] Backport handling of null DateTime parameters in Npgsql 6+ (#3300) Fixes #3291 in 5.3.x Co-authored-by: Alex Zaytsev --- .../Async/NHSpecificTest/GH3291/Fixture.cs | 82 +++++++++++++++++++ .../NHSpecificTest/GH3291/Fixture.cs | 70 ++++++++++++++++ .../NHSpecificTest/GH3291/Mappings.hbm.xml | 11 +++ .../NHSpecificTest/GH3291/Person.cs | 11 +++ .../TestDatabaseSetup.cs | 6 +- src/NHibernate/Driver/NpgsqlDriver.cs | 30 ++++++- 6 files changed, 202 insertions(+), 8 deletions(-) create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH3291/Fixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3291/Fixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3291/Mappings.hbm.xml create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3291/Person.cs diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH3291/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH3291/Fixture.cs new file mode 100644 index 00000000000..3420e7e2199 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH3291/Fixture.cs @@ -0,0 +1,82 @@ +//------------------------------------------------------------------------------ +// +// 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.Linq; +using NUnit.Framework; +using NHibernate.Linq; + +namespace NHibernate.Test.NHSpecificTest.GH3291 +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : BugTestCase + { + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var e1 = new Person { Name = "Bob", DateOfBirth = new DateTime(2009, 12, 23) }; + session.Save(e1); + + var e2 = new Person { Name = "Sally", DateOfBirth = new DateTime(2018, 9, 30) }; + session.Save(e2); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from System.Object").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public async Task LinqAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + DateTime? dateOfSearch = null; + + var result = await (( + from person in session.Query() + where dateOfSearch == null || person.DateOfBirth > dateOfSearch + select person).ToListAsync()); + + Assert.That(result, Has.Count.EqualTo(2)); + } + } + + [Test] + public async Task HqlAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + DateTime? dateOfSearch = null; + + var result = + await (session.CreateQuery("from Person where :DateOfSearch is null OR DateOfBirth > :DateOfSearch") + .SetParameter("DateOfSearch", dateOfSearch, NHibernateUtil.DateTime) + .ListAsync()); + + Assert.That(result, Has.Count.EqualTo(2)); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH3291/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH3291/Fixture.cs new file mode 100644 index 00000000000..1cf8f418f67 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3291/Fixture.cs @@ -0,0 +1,70 @@ +using System; +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH3291 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var e1 = new Person { Name = "Bob", DateOfBirth = new DateTime(2009, 12, 23) }; + session.Save(e1); + + var e2 = new Person { Name = "Sally", DateOfBirth = new DateTime(2018, 9, 30) }; + session.Save(e2); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from System.Object").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public void Linq() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + DateTime? dateOfSearch = null; + + var result = ( + from person in session.Query() + where dateOfSearch == null || person.DateOfBirth > dateOfSearch + select person).ToList(); + + Assert.That(result, Has.Count.EqualTo(2)); + } + } + + [Test] + public void Hql() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + DateTime? dateOfSearch = null; + + var result = + session.CreateQuery("from Person where :DateOfSearch is null OR DateOfBirth > :DateOfSearch") + .SetParameter("DateOfSearch", dateOfSearch, NHibernateUtil.DateTime) + .List(); + + Assert.That(result, Has.Count.EqualTo(2)); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH3291/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH3291/Mappings.hbm.xml new file mode 100644 index 00000000000..1088c98b593 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3291/Mappings.hbm.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/NHibernate.Test/NHSpecificTest/GH3291/Person.cs b/src/NHibernate.Test/NHSpecificTest/GH3291/Person.cs new file mode 100644 index 00000000000..d80efc2e094 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3291/Person.cs @@ -0,0 +1,11 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.GH3291 +{ + class Person + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + public virtual DateTime? DateOfBirth { get; set; } + } +} diff --git a/src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs b/src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs index 5dd5fc8fe22..deea09fb3a5 100644 --- a/src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs +++ b/src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs @@ -182,11 +182,7 @@ private static void SetupNpgsql(Cfg.Configuration cfg) using (var cmd = conn.CreateCommand()) { - cmd.CommandText = - @"CREATE OR REPLACE FUNCTION uuid_generate_v4() - RETURNS uuid - AS '$libdir/uuid-ossp', 'uuid_generate_v4' - VOLATILE STRICT LANGUAGE C;"; + cmd.CommandText = "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";"; cmd.ExecuteNonQuery(); } diff --git a/src/NHibernate/Driver/NpgsqlDriver.cs b/src/NHibernate/Driver/NpgsqlDriver.cs index c638e256221..9a4a4b06771 100644 --- a/src/NHibernate/Driver/NpgsqlDriver.cs +++ b/src/NHibernate/Driver/NpgsqlDriver.cs @@ -1,3 +1,4 @@ +using System; using System.Data; using System.Data.Common; using NHibernate.AdoNet; @@ -74,14 +75,37 @@ protected override void InitializeParameter(DbParameter dbParam, string name, Sq // Since the .NET currency type has 4 decimal places, we use a decimal type in PostgreSQL instead of its native 2 decimal currency type. dbParam.DbType = DbType.Decimal; } - else if (DriverVersionMajor < 6 || sqlType.DbType != DbType.DateTime) + else { dbParam.DbType = sqlType.DbType; } - else + } + + public override void AdjustCommand(DbCommand command) + { + if (DriverVersionMajor >= 6) { - // Let Npgsql 6 driver to decide parameter type + for (var i = 0; i < command.Parameters.Count; i++) + { + var parameter = command.Parameters[i]; + if (parameter.DbType == DbType.DateTime && + parameter.Value is DateTime dateTime && + dateTime.Kind != DateTimeKind.Utc) + { + // There are breaking changes in Npgsql 6 as following: + // UTC DateTime is now strictly mapped to timestamptz, + // while Local/Unspecified DateTime is now strictly mapped to timestamp. + // + // DbType.DateTime now maps to timestamptz, not timestamp. + // DbType.DateTime2 continues to map to timestamp + // + // See more details here: https://www.npgsql.org/doc/release-notes/6.0.html#detailed-notes + parameter.DbType = DbType.DateTime2; + } + } } + + base.AdjustCommand(command); } // Prior to v3, Npgsql was expecting DateTime for time. From c49a2a981e61db9c976cf5354d03a3ad243fb009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Fri, 19 May 2023 23:14:43 +0200 Subject: [PATCH 2/6] Fix SetSnapShot CopyTo variance failure (#3304) Co-authored-by: Alex Zaytsev --- .../UtilityTest/SetSnapShotFixture.cs | 28 ++++++++++++++++- .../Generic/SetHelpers/SetSnapShot.cs | 30 +++++++++++++++---- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs b/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs index e00af722111..47b03b50ec9 100644 --- a/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs +++ b/src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs @@ -1,7 +1,10 @@ -using System.Collections.Generic; +using System; +using System.Collections; +using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using NHibernate.Collection.Generic.SetHelpers; +using NSubstitute.ExceptionExtensions; using NUnit.Framework; namespace NHibernate.Test.UtilityTest @@ -70,6 +73,29 @@ public void TestCopyTo() Assert.That(list, Is.EquivalentTo(array)); } + [Test] + public void TestCopyToObjectArray() + { + var list = new List { "test1", null, "test2" }; + ICollection sn = new SetSnapShot(list); + + var array = new object[3]; + sn.CopyTo(array, 0); + Assert.That(list, Is.EquivalentTo(array)); + } + + [Test] + public void WhenCopyToIsCalledWithIncompatibleArrayTypeThenThrowArgumentOrInvalidCastException() + { + var list = new List { "test1", null, "test2" }; + ICollection sn = new SetSnapShot(list); + + var array = new int[3]; + Assert.That( + () => sn.CopyTo(array, 0), + Throws.ArgumentException.Or.TypeOf()); + } + [Test] public void TestSerialization() { diff --git a/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs b/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs index 0c052a67ba8..edafec312ea 100644 --- a/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs +++ b/src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs @@ -114,12 +114,16 @@ IEnumerator IEnumerable.GetEnumerator() void ICollection.CopyTo(Array array, int index) { - if (!(array is T[] typedArray)) + if (array is T[] typedArray) { - throw new ArgumentException($"Array must be of type {typeof(T[])}.", nameof(array)); + CopyTo(typedArray, index); + return; } - CopyTo(typedArray, index); + if (_hasNull) + array.SetValue(default(T), index); + ICollection keysCollection = _values.Keys; + keysCollection.CopyTo(array, index + (_hasNull ? 1 : 0)); } public int Count => _values.Count + (_hasNull ? 1 : 0); @@ -153,12 +157,26 @@ protected SetSnapShot(SerializationInfo info, StreamingContext context) : base(i void ICollection.CopyTo(Array array, int index) { - if (!(array is T[] typedArray)) + if (array is T[] typedArray) { - throw new ArgumentException($"Array must be of type {typeof(T[])}.", nameof(array)); + CopyTo(typedArray, index); + return; } - CopyTo(typedArray, index); + if (array == null) + throw new ArgumentNullException(nameof(array)); + + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index), index, "Array index cannot be negative"); + + if (index > array.Length || Count > array.Length - index) + throw new ArgumentException("Provided array is too small", nameof(array)); + + foreach (var value in this) + { + array.SetValue(value, index); + index++; + } } bool ICollection.IsSynchronized => false; From c030026bd0c56d9add84ec65ac73dd25bc581815 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Sun, 11 Jun 2023 08:46:06 +0300 Subject: [PATCH 3/6] Fix referencing nullable entity in correlated subquery (#3312) Fixes #3306 --- .../Fixture.cs | 69 +++++++++++++++++++ .../Fixture.cs | 57 +++++++++++++++ .../Mappings.hbm.xml | 27 ++++++++ .../Model.cs | 18 +++++ src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs | 2 +- 5 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Fixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Fixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Mappings.hbm.xml create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Model.cs diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Fixture.cs new file mode 100644 index 00000000000..ba446d194f9 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Fixture.cs @@ -0,0 +1,69 @@ +//------------------------------------------------------------------------------ +// +// 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.Linq; +using NUnit.Framework; +using NHibernate.Linq; + +namespace NHibernate.Test.NHSpecificTest.GH3306NullableEntityCorrelatedSubquery +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : BugTestCase + { + private const string NAME_JOE = "Joe"; + private const string NAME_ALLEN = "Allen"; + + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var joe = new Customer { Name = NAME_JOE }; + session.Save(joe); + + var allen = new Customer { Name = NAME_ALLEN }; + session.Save(allen); + + var joeInvoice0 = new Invoice { Customer = joe, Number = 0 }; + session.Save(joeInvoice0); + + var allenInvoice1 = new Invoice { Customer = allen, Number = 1 }; + session.Save(allenInvoice1); + + tx.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + session.Delete("from Invoice"); + session.Delete("from Customer"); + tx.Commit(); + } + } + + [Test] + public async Task NullableEntityInCorrelatedSubqueryAsync() + { + using (var s = OpenSession()) + { + var customers = s.Query().Where(c => c.Name == NAME_JOE); + var results = await (s.Query() + .Where(i => customers.Any(c => c.Invoices.Any(ci => ci.Customer == i.Customer))).ToListAsync()); + + Assert.That(results.Count, Is.EqualTo(1)); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Fixture.cs new file mode 100644 index 00000000000..d1d511eca59 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Fixture.cs @@ -0,0 +1,57 @@ +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH3306NullableEntityCorrelatedSubquery +{ + [TestFixture] + public class Fixture : BugTestCase + { + private const string NAME_JOE = "Joe"; + private const string NAME_ALLEN = "Allen"; + + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var joe = new Customer { Name = NAME_JOE }; + session.Save(joe); + + var allen = new Customer { Name = NAME_ALLEN }; + session.Save(allen); + + var joeInvoice0 = new Invoice { Customer = joe, Number = 0 }; + session.Save(joeInvoice0); + + var allenInvoice1 = new Invoice { Customer = allen, Number = 1 }; + session.Save(allenInvoice1); + + tx.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + session.Delete("from Invoice"); + session.Delete("from Customer"); + tx.Commit(); + } + } + + [Test] + public void NullableEntityInCorrelatedSubquery() + { + using (var s = OpenSession()) + { + var customers = s.Query().Where(c => c.Name == NAME_JOE); + var results = s.Query() + .Where(i => customers.Any(c => c.Invoices.Any(ci => ci.Customer == i.Customer))).ToList(); + + Assert.That(results.Count, Is.EqualTo(1)); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Mappings.hbm.xml new file mode 100644 index 00000000000..515584fe116 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Mappings.hbm.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Model.cs b/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Model.cs new file mode 100644 index 00000000000..2c472579b00 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3306NullableEntityCorrelatedSubquery/Model.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.GH3306NullableEntityCorrelatedSubquery +{ + public class Customer + { + public virtual int ID { get; protected set; } + public virtual ISet Invoices { get; set; } + public virtual string Name { get; set; } + } + + public class Invoice + { + public virtual int ID { get; protected set; } + public virtual Customer Customer { get; set; } + public virtual int Number { get; set; } + } +} diff --git a/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs b/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs index f7743426826..2049edefb6e 100644 --- a/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs +++ b/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs @@ -389,7 +389,7 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string bool joinIsNeeded; //For nullable entity comparisons we always need to add join (like not constrained one-to-one or not-found ignore associations) - bool comparisonWithNullableEntity = entityType.IsNullable && Walker.IsComparativeExpressionClause; + bool comparisonWithNullableEntity = entityType.IsNullable && Walker.IsComparativeExpressionClause && !IsCorrelatedSubselect; if ( IsDotNode( parent ) ) { From e9eab6705a8d9ed4b54a5b77d64168fa34eb9a28 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Sun, 11 Jun 2023 11:30:38 +0300 Subject: [PATCH 4/6] Fix LINQ cross join issue with InformixDialect (#3313) Fixes #3294 --- src/NHibernate/Dialect/InformixDialect.cs | 3 +++ src/NHibernate/Dialect/InformixDialect0940.cs | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NHibernate/Dialect/InformixDialect.cs b/src/NHibernate/Dialect/InformixDialect.cs index 2f942815a57..4be77acd721 100644 --- a/src/NHibernate/Dialect/InformixDialect.cs +++ b/src/NHibernate/Dialect/InformixDialect.cs @@ -333,6 +333,9 @@ public override JoinFragment CreateOuterJoinFragment() return new InformixJoinFragment(); } + /// + public override bool SupportsCrossJoin => false; + /// The SQL literal value to which this database maps boolean values. /// The boolean value /// The appropriate SQL literal. diff --git a/src/NHibernate/Dialect/InformixDialect0940.cs b/src/NHibernate/Dialect/InformixDialect0940.cs index bdfcae4f27f..13563df43e8 100644 --- a/src/NHibernate/Dialect/InformixDialect0940.cs +++ b/src/NHibernate/Dialect/InformixDialect0940.cs @@ -126,10 +126,7 @@ public override JoinFragment CreateOuterJoinFragment() return new ANSIJoinFragment(); } - /// - public override bool SupportsCrossJoin => false; - - /// + /// /// Does this Dialect have some kind of LIMIT syntax? /// /// False, unless overridden. From 469b8643b81708f3bfc6e9da0d3ead3fa162324b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Sun, 11 Jun 2023 19:02:22 +0200 Subject: [PATCH 5/6] Enable dev builds for 5.3.17 --- build-common/NHibernate.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-common/NHibernate.props b/build-common/NHibernate.props index 9f4d60b50c2..24d559ff785 100644 --- a/build-common/NHibernate.props +++ b/build-common/NHibernate.props @@ -3,9 +3,9 @@ 5.3 - 16 + 17 - + dev $(NhVersion).$(VersionPatch) $(VersionSuffix).$(BuildNumber) From 0e08e919ba5aefe965b09e64e2af5fd8ea9813ba 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, 13 Jun 2023 00:10:13 +0200 Subject: [PATCH 6/6] Release 5.3.17 (#3315) --- build-common/NHibernate.props | 2 +- releasenotes.txt | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/build-common/NHibernate.props b/build-common/NHibernate.props index 24d559ff785..714717ed58a 100644 --- a/build-common/NHibernate.props +++ b/build-common/NHibernate.props @@ -5,7 +5,7 @@ 5.3 17 - dev + $(NhVersion).$(VersionPatch) $(VersionSuffix).$(BuildNumber) diff --git a/releasenotes.txt b/releasenotes.txt index feca1375199..1224428c9b6 100644 --- a/releasenotes.txt +++ b/releasenotes.txt @@ -1,4 +1,23 @@ -Build 5.3.16 +Build 5.3.17 +============================= + +Release notes - NHibernate - Version 5.3.17 + +5 issues were resolved in this release. + +** Bug + + * #3306 Invalid SQL when referencing nullable entity in correlated subquery + * #3304 Fix SetSnapShot CopyTo variance failure + * #3294 Undefined join type failure with cross joins and Informix + +** Task + + * #3315 Release 5.3.17 + * #3300 Backport handling of null DateTime parameters in Npgsql 6+ + + +Build 5.3.16 ============================= Release notes - NHibernate - Version 5.3.16