diff --git a/src/NHibernate.Test/Async/NHSpecificTest/NH3506/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/NH3506/Fixture.cs
new file mode 100644
index 00000000000..3ee9ae36268
--- /dev/null
+++ b/src/NHibernate.Test/Async/NHSpecificTest/NH3506/Fixture.cs
@@ -0,0 +1,120 @@
+//------------------------------------------------------------------------------
+//
+// 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 NHibernate.SqlCommand;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH3506
+{
+ using System.Threading.Tasks;
+ [TestFixture]
+ public class FixtureAsync : BugTestCase
+ {
+ private Department _department;
+
+ private Employee _employee1;
+
+ private Employee _employee2;
+
+ protected override void OnSetUp()
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ _department = new Department();
+
+ _employee1 = new Employee
+ {
+ Department = _department
+ };
+
+ _employee2 = new Employee();
+
+ session.Save(_department);
+ session.Save(_employee1);
+ session.Save(_employee2);
+
+ tx.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ session.Delete(_department);
+ session.Delete(_employee1);
+ session.Delete(_employee2);
+
+ tx.Commit();
+ }
+ }
+
+ [Theory]
+ public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_HQLAsync(bool enableFilter)
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ if (enableFilter)
+ session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
+
+ var employees = await (session.CreateQuery("select e from Employee e left join e.Department d")
+ .ListAsync());
+
+ Assert.That(employees.Count, Is.EqualTo(2));
+
+ await (tx.CommitAsync());
+ }
+ }
+
+ [Theory]
+ public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_ICriteriaAsync(bool enableFilter)
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ if (enableFilter)
+ session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
+
+ var employees = await (session.CreateCriteria()
+ .CreateCriteria("Department", JoinType.LeftOuterJoin)
+ .ListAsync());
+
+ Assert.That(employees.Count, Is.EqualTo(2));
+
+ await (tx.CommitAsync());
+ }
+ }
+
+ [Theory]
+ public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_QueryOverAsync(bool enableFilter)
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ if (enableFilter)
+ session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
+
+ var employees = await (session.QueryOver()
+ .JoinQueryOver(x => x.Department, JoinType.LeftOuterJoin)
+ .ListAsync());
+
+ Assert.That(employees.Count, Is.EqualTo(2));
+
+ await (tx.CommitAsync());
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/BaseClass.cs b/src/NHibernate.Test/NHSpecificTest/NH3506/BaseClass.cs
new file mode 100644
index 00000000000..1e28c529c42
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/NH3506/BaseClass.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace NHibernate.Test.NHSpecificTest.NH3506
+{
+ public class BaseClass
+ {
+ public virtual Guid Id { get; set; }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/Department.cs b/src/NHibernate.Test/NHSpecificTest/NH3506/Department.cs
new file mode 100644
index 00000000000..f3d3a833a4c
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/NH3506/Department.cs
@@ -0,0 +1,6 @@
+namespace NHibernate.Test.NHSpecificTest.NH3506
+{
+ public class Department : BaseClass
+ {
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/Employee.cs b/src/NHibernate.Test/NHSpecificTest/NH3506/Employee.cs
new file mode 100644
index 00000000000..7e15c859882
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/NH3506/Employee.cs
@@ -0,0 +1,7 @@
+namespace NHibernate.Test.NHSpecificTest.NH3506
+{
+ public class Employee : BaseClass
+ {
+ public virtual Department Department { get; set; }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/NH3506/Fixture.cs
new file mode 100644
index 00000000000..ffc6a821136
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/NH3506/Fixture.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NHibernate.SqlCommand;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH3506
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ private Department _department;
+
+ private Employee _employee1;
+
+ private Employee _employee2;
+
+ protected override void OnSetUp()
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ _department = new Department();
+
+ _employee1 = new Employee
+ {
+ Department = _department
+ };
+
+ _employee2 = new Employee();
+
+ session.Save(_department);
+ session.Save(_employee1);
+ session.Save(_employee2);
+
+ tx.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ session.Delete(_department);
+ session.Delete(_employee1);
+ session.Delete(_employee2);
+
+ tx.Commit();
+ }
+ }
+
+ [Theory]
+ public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_HQL(bool enableFilter)
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ if (enableFilter)
+ session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
+
+ var employees = session.CreateQuery("select e from Employee e left join e.Department d")
+ .List();
+
+ Assert.That(employees.Count, Is.EqualTo(2));
+
+ tx.Commit();
+ }
+ }
+
+ [Theory]
+ public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_ICriteria(bool enableFilter)
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ if (enableFilter)
+ session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
+
+ var employees = session.CreateCriteria()
+ .CreateCriteria("Department", JoinType.LeftOuterJoin)
+ .List();
+
+ Assert.That(employees.Count, Is.EqualTo(2));
+
+ tx.Commit();
+ }
+ }
+
+ [Theory]
+ public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_QueryOver(bool enableFilter)
+ {
+ using (var session = OpenSession())
+ using (var tx = session.BeginTransaction())
+ {
+ if (enableFilter)
+ session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
+
+ var employees = session.QueryOver()
+ .JoinQueryOver(x => x.Department, JoinType.LeftOuterJoin)
+ .List();
+
+ Assert.That(employees.Count, Is.EqualTo(2));
+
+ tx.Commit();
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/NH3506/Mappings.hbm.xml
new file mode 100644
index 00000000000..1d686b9d3a4
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/NH3506/Mappings.hbm.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/NHibernate/Loader/JoinWalker.cs b/src/NHibernate/Loader/JoinWalker.cs
index fe3ea666811..372ef8bed73 100644
--- a/src/NHibernate/Loader/JoinWalker.cs
+++ b/src/NHibernate/Loader/JoinWalker.cs
@@ -687,7 +687,9 @@ protected JoinFragment MergeOuterJoins(IList associati
outerjoin.ToFromFragmentString.IndexOfCaseInsensitive(manyToOneFilterFragment) == -1;
if (joinClauseDoesNotContainsFilterAlready)
{
- outerjoin.AddCondition(manyToOneFilterFragment);
+ // Ensure that the join condition is added to the join, not the where clause.
+ // Adding the condition to the where clause causes left joins to become inner joins.
+ outerjoin.AddFromFragmentString(new SqlString(manyToOneFilterFragment));
}
}
}