diff --git a/src/NHibernate.Test/NHSpecificTest/GH3609/Entities.cs b/src/NHibernate.Test/NHSpecificTest/GH3609/Entities.cs new file mode 100644 index 00000000000..28857618b4f --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3609/Entities.cs @@ -0,0 +1,24 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.GH3609 +{ + public class Order + { + public virtual long Id { get; set; } + + public virtual string UniqueId { get; set; } = Guid.NewGuid().ToString(); + + public virtual DateTime CreatedDate { get; set; } + } + + public class LineItem + { + public virtual long Id { get; set; } + + public virtual Order Order { get; set; } + + public virtual string ItemName { get; set; } + + public virtual decimal Amount { get; set; } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH3609/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH3609/Fixture.cs new file mode 100644 index 00000000000..42e532f5ad0 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3609/Fixture.cs @@ -0,0 +1,81 @@ +using System; +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH3609 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + + var order = new Order + { + UniqueId = "0ab92479-8a17-4dbc-9bef-ce4344940cec", + CreatedDate = new DateTime(2024, 09, 24) + }; + session.Save(order); + + session.Save(new LineItem { Order = order, ItemName = "Bananas", Amount = 5 }); + + 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 QueryWithAny() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // This form of query is how we first discovered the issue. This is a simplified reproduction of the + // sort of Linq that we were using in our app. It seems to occur when we force an EXISTS( ... ) subquery. + var validOrders = session.Query().Where(x => x.CreatedDate > new DateTime(2024, 9, 10)); + var orderCount = session.Query().Count(x => validOrders.Any(y => y == x.Order)); + + Assert.That(orderCount, Is.EqualTo(1)); + } + } + + [Test] + public void QueryWithContains() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + var validOrders = session.Query().Where(x => x.CreatedDate > new DateTime(2024, 9, 10)); + var orderCount = session.Query().Count(x => validOrders.Contains(x.Order)); + + Assert.That(orderCount, Is.EqualTo(1)); + } + } + + [Test] + public void SimpleQueryForDataWhichWasInsertedViaAdoShouldProvideExpectedResults() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // This style of equivalent query does not exhibit the problem. This test passes no matter which NH version. + var lineItem = session.Query().FirstOrDefault(x => x.Order.CreatedDate > new DateTime(2024, 9, 10)); + Assert.That(lineItem, Is.Not.Null); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH3609/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH3609/Mappings.hbm.xml new file mode 100644 index 00000000000..e21dd4871b6 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3609/Mappings.hbm.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + diff --git a/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs b/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs index f7743426826..1dc740cfc4e 100644 --- a/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs +++ b/src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs @@ -153,7 +153,7 @@ public override void ResolveFirstChild() string propName = property.Text; _propertyName = propName; - // If the uresolved property path isn't set yet, just use the property name. + // If the unresolved property path isn't set yet, just use the property name. if (_propertyPath == null) { _propertyPath = propName;