Skip to content

Commit 1dec74d

Browse files
committed
Fix for queries with implicit joins
1 parent 58b6c04 commit 1dec74d

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
using System.Linq;
1212
using System.Text.RegularExpressions;
1313
using NHibernate.Cfg.MappingSchema;
14+
using NHibernate.Linq;
1415
using NHibernate.Mapping.ByCode;
1516
using NHibernate.Test.Hql.EntityJoinHqlTestEntities;
1617
using NUnit.Framework;
17-
using NHibernate.Linq;
1818

1919
namespace NHibernate.Test.Hql
2020
{
@@ -298,7 +298,17 @@ public async Task NullableOneIsNullLinqAsync()
298298
{
299299
using (var session = OpenSession())
300300
{
301-
var entity = await (session.Query<NullableOwner>().Where(x => x.OneToOne == null).FirstOrDefaultAsync());
301+
var entity = await (session.Query<NullableOwner>().Where(x => x.OneToOne == null).SingleOrDefaultAsync());
302+
Assert.That(entity, Is.Not.Null);
303+
}
304+
}
305+
306+
[Test(Description = "GH-2611")]
307+
public async Task NullableOneFetchIsNullLinqAsync()
308+
{
309+
using (var session = OpenSession())
310+
{
311+
var entity = await (session.Query<NullableOwner>().Fetch(x => x.OneToOne).Where(x => x.OneToOne == null).SingleOrDefaultAsync());
302312
Assert.That(entity, Is.Not.Null);
303313
}
304314
}
@@ -309,15 +319,14 @@ public async Task NullableOneToOneFetchQueryIsNotAffected2Async()
309319
using (var sqlLog = new SqlLogSpy())
310320
using (var session = OpenSession())
311321
{
312-
var entities =
322+
var entity =
313323
await (session
314324
.CreateQuery(
315325
"select ex "
316326
+ "from NullableOwner ex left join fetch ex.OneToOne o "
317327
+ "where o.Id is null "
318328
)
319-
.ListAsync<NullableOwner>());
320-
var entity = entities[0];
329+
.UniqueResultAsync<NullableOwner>());
321330

322331
Assert.That(entity, Is.Not.Null);
323332
Assert.That(Regex.Matches(sqlLog.GetWholeLog(), "OneToOneEntity").Count, Is.EqualTo(1));

src/NHibernate.Test/Hql/EntityJoinHqlTest.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Linq;
22
using System.Text.RegularExpressions;
33
using NHibernate.Cfg.MappingSchema;
4+
using NHibernate.Linq;
45
using NHibernate.Mapping.ByCode;
56
using NHibernate.Test.Hql.EntityJoinHqlTestEntities;
67
using NUnit.Framework;
@@ -286,7 +287,17 @@ public void NullableOneIsNullLinq()
286287
{
287288
using (var session = OpenSession())
288289
{
289-
var entity = session.Query<NullableOwner>().Where(x => x.OneToOne == null).FirstOrDefault();
290+
var entity = session.Query<NullableOwner>().Where(x => x.OneToOne == null).SingleOrDefault();
291+
Assert.That(entity, Is.Not.Null);
292+
}
293+
}
294+
295+
[Test(Description = "GH-2611")]
296+
public void NullableOneFetchIsNullLinq()
297+
{
298+
using (var session = OpenSession())
299+
{
300+
var entity = session.Query<NullableOwner>().Fetch(x => x.OneToOne).Where(x => x.OneToOne == null).SingleOrDefault();
290301
Assert.That(entity, Is.Not.Null);
291302
}
292303
}
@@ -297,15 +308,14 @@ public void NullableOneToOneFetchQueryIsNotAffected2()
297308
using (var sqlLog = new SqlLogSpy())
298309
using (var session = OpenSession())
299310
{
300-
var entities =
311+
var entity =
301312
session
302313
.CreateQuery(
303314
"select ex "
304315
+ "from NullableOwner ex left join fetch ex.OneToOne o "
305316
+ "where o.Id is null "
306317
)
307-
.List<NullableOwner>();
308-
var entity = entities[0];
318+
.UniqueResult<NullableOwner>();
309319

310320
Assert.That(entity, Is.Not.Null);
311321
Assert.That(Regex.Matches(sqlLog.GetWholeLog(), "OneToOneEntity").Count, Is.EqualTo(1));

src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Linq;
23
using Antlr.Runtime;
34

45
using NHibernate.Engine;
@@ -412,7 +413,11 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string
412413
if (Walker.IsComparativeExpressionClause && entityType.IsNullable)
413414
{
414415
joinIsNeeded = comparisonWithNullableEntity = true;
415-
_joinType = JoinType.LeftOuterJoin;
416+
417+
//TODO: Fix this hack. We should always left join here. Skip left join for nullable entity if query contains implicit joins. We currently don't support such queries (see OneToOneCompositeQueryCompareWithJoin)
418+
var fromJoins = ASTUtil.CollectChildren<FromElement>(Walker.CurrentFromClause, x => x is FromElement fe && !fe.IsImplied && fe.Type == HqlSqlWalker.FROM_FRAGMENT);
419+
if(fromJoins.Count == 1)
420+
_joinType = JoinType.LeftOuterJoin;
416421
}
417422
else
418423
{

0 commit comments

Comments
 (0)