Skip to content

Commit 9bd9a80

Browse files
froedephazzik
authored andcommitted
Fix ICriteria/QueryOver create incorrect left join condition when table-per-hierarchy is used with filters (#268)
Fixes #1366
1 parent 71aa211 commit 9bd9a80

File tree

7 files changed

+280
-1
lines changed

7 files changed

+280
-1
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Linq;
14+
using NHibernate.SqlCommand;
15+
using NUnit.Framework;
16+
17+
namespace NHibernate.Test.NHSpecificTest.NH3506
18+
{
19+
using System.Threading.Tasks;
20+
[TestFixture]
21+
public class FixtureAsync : BugTestCase
22+
{
23+
private Department _department;
24+
25+
private Employee _employee1;
26+
27+
private Employee _employee2;
28+
29+
protected override void OnSetUp()
30+
{
31+
using (var session = OpenSession())
32+
using (var tx = session.BeginTransaction())
33+
{
34+
_department = new Department();
35+
36+
_employee1 = new Employee
37+
{
38+
Department = _department
39+
};
40+
41+
_employee2 = new Employee();
42+
43+
session.Save(_department);
44+
session.Save(_employee1);
45+
session.Save(_employee2);
46+
47+
tx.Commit();
48+
}
49+
}
50+
51+
protected override void OnTearDown()
52+
{
53+
using (var session = OpenSession())
54+
using (var tx = session.BeginTransaction())
55+
{
56+
session.Delete(_department);
57+
session.Delete(_employee1);
58+
session.Delete(_employee2);
59+
60+
tx.Commit();
61+
}
62+
}
63+
64+
[Theory]
65+
public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_HQLAsync(bool enableFilter)
66+
{
67+
using (var session = OpenSession())
68+
using (var tx = session.BeginTransaction())
69+
{
70+
if (enableFilter)
71+
session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
72+
73+
var employees = await (session.CreateQuery("select e from Employee e left join e.Department d")
74+
.ListAsync<Employee>());
75+
76+
Assert.That(employees.Count, Is.EqualTo(2));
77+
78+
await (tx.CommitAsync());
79+
}
80+
}
81+
82+
[Theory]
83+
public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_ICriteriaAsync(bool enableFilter)
84+
{
85+
using (var session = OpenSession())
86+
using (var tx = session.BeginTransaction())
87+
{
88+
if (enableFilter)
89+
session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
90+
91+
var employees = await (session.CreateCriteria<Employee>()
92+
.CreateCriteria("Department", JoinType.LeftOuterJoin)
93+
.ListAsync<Employee>());
94+
95+
Assert.That(employees.Count, Is.EqualTo(2));
96+
97+
await (tx.CommitAsync());
98+
}
99+
}
100+
101+
[Theory]
102+
public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_QueryOverAsync(bool enableFilter)
103+
{
104+
using (var session = OpenSession())
105+
using (var tx = session.BeginTransaction())
106+
{
107+
if (enableFilter)
108+
session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
109+
110+
var employees = await (session.QueryOver<Employee>()
111+
.JoinQueryOver(x => x.Department, JoinType.LeftOuterJoin)
112+
.ListAsync());
113+
114+
Assert.That(employees.Count, Is.EqualTo(2));
115+
116+
await (tx.CommitAsync());
117+
}
118+
}
119+
}
120+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH3506
4+
{
5+
public class BaseClass
6+
{
7+
public virtual Guid Id { get; set; }
8+
}
9+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace NHibernate.Test.NHSpecificTest.NH3506
2+
{
3+
public class Department : BaseClass
4+
{
5+
}
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace NHibernate.Test.NHSpecificTest.NH3506
2+
{
3+
public class Employee : BaseClass
4+
{
5+
public virtual Department Department { get; set; }
6+
}
7+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using NHibernate.SqlCommand;
5+
using NUnit.Framework;
6+
7+
namespace NHibernate.Test.NHSpecificTest.NH3506
8+
{
9+
[TestFixture]
10+
public class Fixture : BugTestCase
11+
{
12+
private Department _department;
13+
14+
private Employee _employee1;
15+
16+
private Employee _employee2;
17+
18+
protected override void OnSetUp()
19+
{
20+
using (var session = OpenSession())
21+
using (var tx = session.BeginTransaction())
22+
{
23+
_department = new Department();
24+
25+
_employee1 = new Employee
26+
{
27+
Department = _department
28+
};
29+
30+
_employee2 = new Employee();
31+
32+
session.Save(_department);
33+
session.Save(_employee1);
34+
session.Save(_employee2);
35+
36+
tx.Commit();
37+
}
38+
}
39+
40+
protected override void OnTearDown()
41+
{
42+
using (var session = OpenSession())
43+
using (var tx = session.BeginTransaction())
44+
{
45+
session.Delete(_department);
46+
session.Delete(_employee1);
47+
session.Delete(_employee2);
48+
49+
tx.Commit();
50+
}
51+
}
52+
53+
[Theory]
54+
public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_HQL(bool enableFilter)
55+
{
56+
using (var session = OpenSession())
57+
using (var tx = session.BeginTransaction())
58+
{
59+
if (enableFilter)
60+
session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
61+
62+
var employees = session.CreateQuery("select e from Employee e left join e.Department d")
63+
.List<Employee>();
64+
65+
Assert.That(employees.Count, Is.EqualTo(2));
66+
67+
tx.Commit();
68+
}
69+
}
70+
71+
[Theory]
72+
public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_ICriteria(bool enableFilter)
73+
{
74+
using (var session = OpenSession())
75+
using (var tx = session.BeginTransaction())
76+
{
77+
if (enableFilter)
78+
session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
79+
80+
var employees = session.CreateCriteria<Employee>()
81+
.CreateCriteria("Department", JoinType.LeftOuterJoin)
82+
.List<Employee>();
83+
84+
Assert.That(employees.Count, Is.EqualTo(2));
85+
86+
tx.Commit();
87+
}
88+
}
89+
90+
[Theory]
91+
public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_QueryOver(bool enableFilter)
92+
{
93+
using (var session = OpenSession())
94+
using (var tx = session.BeginTransaction())
95+
{
96+
if (enableFilter)
97+
session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow);
98+
99+
var employees = session.QueryOver<Employee>()
100+
.JoinQueryOver(x => x.Department, JoinType.LeftOuterJoin)
101+
.List();
102+
103+
Assert.That(employees.Count, Is.EqualTo(2));
104+
105+
tx.Commit();
106+
}
107+
}
108+
}
109+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
4+
namespace="NHibernate.Test.NHSpecificTest.NH3506"
5+
assembly="NHibernate.Test">
6+
7+
<class name="BaseClass">
8+
<id name="Id">
9+
<generator class="guid.comb" />
10+
</id>
11+
<discriminator column="discriminator" type="String" />
12+
13+
<subclass name="Employee" discriminator-value="Emp">
14+
<many-to-one name="Department" class="Department" />
15+
</subclass>
16+
17+
<subclass name="Department" discriminator-value="Dep">
18+
</subclass>
19+
</class>
20+
21+
<filter-def name="ValidAtFilter">
22+
<filter-param name="CurrentDate" type="DateTime" />
23+
<![CDATA[ValidAt = :CurrentDate]]>
24+
</filter-def>
25+
26+
</hibernate-mapping>

src/NHibernate/Loader/JoinWalker.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,9 @@ protected JoinFragment MergeOuterJoins(IList<OuterJoinableAssociation> associati
827827
outerjoin.ToFromFragmentString.IndexOfCaseInsensitive(manyToOneFilterFragment) == -1;
828828
if (joinClauseDoesNotContainsFilterAlready)
829829
{
830-
outerjoin.AddCondition(manyToOneFilterFragment);
830+
// Ensure that the join condition is added to the join, not the where clause.
831+
// Adding the condition to the where clause causes left joins to become inner joins.
832+
outerjoin.AddFromFragmentString(new SqlString(manyToOneFilterFragment));
831833
}
832834
}
833835
}

0 commit comments

Comments
 (0)