Skip to content

Commit fc8d55c

Browse files
Merge 5.3.15 into 5.4.x
2 parents ecf8d78 + e14704f commit fc8d55c

File tree

8 files changed

+270
-15
lines changed

8 files changed

+270
-15
lines changed

.github/workflows/GenerateAsyncCode.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
token: ${{ secrets.NHIBERNATE_BOT_TOKEN }}
2020

2121
- name: Setup .NET
22-
uses: actions/setup-dotnet@v2
22+
uses: actions/setup-dotnet@v3
2323
with:
2424
dotnet-version: 6.0.x
2525

releasenotes.txt

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,24 @@ Release notes - NHibernate - Version 5.4.0
186186
* #2242 Test case for NH-3972 - SQL error when selecting a column of a subclass when sibling classes have a column of the same name
187187

188188

189+
Build 5.3.15
190+
=============================
191+
192+
Release notes - NHibernate - Version 5.3.15
193+
194+
4 issues were resolved in this release.
195+
196+
** Bug
197+
198+
* #3218 Failure of contains subquery with parameter
199+
* #3187 Fix mixing implied implicit and left joins in HQL for v5.3
200+
201+
** Task
202+
203+
* #3225 Release 5.3.15
204+
* #3222 Automatically generate async code on pull requests for 5.3
205+
206+
189207
Build 5.3.14
190208
=============================
191209

@@ -195,8 +213,8 @@ Release notes - NHibernate - Version 5.3.14
195213

196214
** Bug
197215

198-
#3169 InvalidOperationException: This transformer is not initialized by Cached Query
199-
#3164 Fetching a lazy loaded component regression
216+
* #3169 InvalidOperationException: This transformer is not initialized by Cached Query
217+
* #3164 Fetching a lazy loaded component regression
200218

201219
** Task
202220

@@ -212,14 +230,14 @@ Release notes - NHibernate - Version 5.3.13
212230

213231
** Bug
214232

215-
#3134 ManyToMany - Tries to select not existing column in Mapping Table
216-
#3113 Join fails on Oracle9Dialect
217-
#3030 Memory leak named parameter holds entity references
233+
* #3134 ManyToMany - Tries to select not existing column in Mapping Table
234+
* #3113 Join fails on Oracle9Dialect
235+
* #3030 Memory leak named parameter holds entity references
218236

219237
** Improvement
220238

221-
#3120 Guards against use of a disposed session factory
222-
#2994 Npgsql 6 is not compatible
239+
* #3120 Guards against use of a disposed session factory
240+
* #2994 Npgsql 6 is not compatible
223241

224242
** Task
225243

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,13 +359,17 @@ from x2 in session.Query<NullableOwner>()
359359
var withNullOrValidList = await (session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == validManyToOne.Id || x.ManyToOne == null).ToListAsync());
360360
var withNullOrValidList2 = await (session.Query<NullableOwner>().Where(x => x.ManyToOne == null || x.ManyToOne.Id == validManyToOne.Id).ToListAsync());
361361

362+
//GH-3185
363+
var mixImplicitAndLeftJoinList = await (session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == validManyToOne.Id && x.OneToOne == null).ToListAsync());
364+
362365
Assert.That(fullList.Count, Is.EqualTo(2));
363366
Assert.That(withValidManyToOneList.Count, Is.EqualTo(0));
364367
Assert.That(withValidManyToOneList2.Count, Is.EqualTo(0));
365368
Assert.That(withNullManyToOneList.Count, Is.EqualTo(2));
366369
Assert.That(withNullManyToOneJoinedList.Count, Is.EqualTo(2));
367370
Assert.That(withNullOrValidList.Count, Is.EqualTo(2));
368371
Assert.That(withNullOrValidList2.Count, Is.EqualTo(2));
372+
Assert.That(mixImplicitAndLeftJoinList.Count, Is.EqualTo(1));
369373
}
370374
}
371375

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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.Linq;
13+
using NHibernate.Cfg.MappingSchema;
14+
using NHibernate.Mapping.ByCode;
15+
using NUnit.Framework;
16+
using NHibernate.Linq;
17+
18+
namespace NHibernate.Test.NHSpecificTest.GH3218
19+
{
20+
using System.Threading.Tasks;
21+
[TestFixture]
22+
public class ContainsParameterFixtureAsync : TestCaseMappingByCode
23+
{
24+
protected override HbmMapping GetMappings()
25+
{
26+
var mapper = new ModelMapper();
27+
mapper.Class<Child>(rc =>
28+
{
29+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
30+
rc.Property(x => x.Name);
31+
rc.Component(
32+
x => x.Component,
33+
ekm =>
34+
{
35+
ekm.Property(ek => ek.Id1);
36+
ekm.Property(ek => ek.Id2);
37+
});
38+
});
39+
mapper.Class<Entity>(rc =>
40+
{
41+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
42+
rc.Property(x => x.Name);
43+
rc.Bag(x => x.List, m => { }, r => r.OneToMany());
44+
});
45+
46+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
47+
}
48+
49+
[Test]
50+
public async Task ContainsOnIdAsync()
51+
{
52+
using (var session = OpenSession())
53+
{
54+
Guid clientId = Guid.NewGuid();
55+
await (session.Query<Entity>().Where(x => x.List.Select(l => l.Id).Contains(clientId)).ToListAsync());
56+
}
57+
}
58+
59+
[Test]
60+
public async Task ContainsOnNameWithInnerSubqueryAsync()
61+
{
62+
using (var session = OpenSession())
63+
{
64+
var clientId = "aa";
65+
await (session.Query<Entity>().Where(x =>
66+
x.List.Where(l => session.Query<Entity>().Any(s => s.Name == l.Name)).Select(l => l.Name)
67+
.Contains(clientId)).ToListAsync());
68+
}
69+
}
70+
71+
[Test]
72+
public async Task ContainsOnEntityAsync()
73+
{
74+
using (var session = OpenSession())
75+
{
76+
var client = await (session.LoadAsync<Child>(Guid.NewGuid()));
77+
await (session.Query<Entity>().Where(x => x.List.Contains(client)).ToListAsync());
78+
}
79+
}
80+
81+
[Test]
82+
public async Task ContainsOnNameAsync()
83+
{
84+
using (var session = OpenSession())
85+
{
86+
var client = "aaa";
87+
await (session.Query<Entity>().Where(x => x.List.Select(l => l.Name).Contains(client)).ToListAsync());
88+
}
89+
}
90+
91+
[Test]
92+
public async Task ContainsOnComponentAsync()
93+
{
94+
using (var session = OpenSession())
95+
{
96+
var client = new CompositeKey() { Id1 = 1, Id2 = 2 };
97+
await (session.Query<Entity>().Where(x => x.List.Select(l => l.Component).Contains(client)).ToListAsync());
98+
}
99+
}
100+
}
101+
}

src/NHibernate.Test/Hql/EntityJoinHqlTest.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,13 +347,17 @@ from x2 in session.Query<NullableOwner>()
347347
var withNullOrValidList = session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == validManyToOne.Id || x.ManyToOne == null).ToList();
348348
var withNullOrValidList2 = session.Query<NullableOwner>().Where(x => x.ManyToOne == null || x.ManyToOne.Id == validManyToOne.Id).ToList();
349349

350+
//GH-3185
351+
var mixImplicitAndLeftJoinList = session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == validManyToOne.Id && x.OneToOne == null).ToList();
352+
350353
Assert.That(fullList.Count, Is.EqualTo(2));
351354
Assert.That(withValidManyToOneList.Count, Is.EqualTo(0));
352355
Assert.That(withValidManyToOneList2.Count, Is.EqualTo(0));
353356
Assert.That(withNullManyToOneList.Count, Is.EqualTo(2));
354357
Assert.That(withNullManyToOneJoinedList.Count, Is.EqualTo(2));
355358
Assert.That(withNullOrValidList.Count, Is.EqualTo(2));
356359
Assert.That(withNullOrValidList2.Count, Is.EqualTo(2));
360+
Assert.That(mixImplicitAndLeftJoinList.Count, Is.EqualTo(1));
357361
}
358362
}
359363

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System;
2+
using System.Linq;
3+
using NHibernate.Cfg.MappingSchema;
4+
using NHibernate.Mapping.ByCode;
5+
using NUnit.Framework;
6+
7+
namespace NHibernate.Test.NHSpecificTest.GH3218
8+
{
9+
[TestFixture]
10+
public class ContainsParameterFixture : TestCaseMappingByCode
11+
{
12+
protected override HbmMapping GetMappings()
13+
{
14+
var mapper = new ModelMapper();
15+
mapper.Class<Child>(rc =>
16+
{
17+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
18+
rc.Property(x => x.Name);
19+
rc.Component(
20+
x => x.Component,
21+
ekm =>
22+
{
23+
ekm.Property(ek => ek.Id1);
24+
ekm.Property(ek => ek.Id2);
25+
});
26+
});
27+
mapper.Class<Entity>(rc =>
28+
{
29+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
30+
rc.Property(x => x.Name);
31+
rc.Bag(x => x.List, m => { }, r => r.OneToMany());
32+
});
33+
34+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
35+
}
36+
37+
[Test]
38+
public void ContainsOnId()
39+
{
40+
using (var session = OpenSession())
41+
{
42+
Guid clientId = Guid.NewGuid();
43+
session.Query<Entity>().Where(x => x.List.Select(l => l.Id).Contains(clientId)).ToList();
44+
}
45+
}
46+
47+
[Test]
48+
public void ContainsOnNameWithInnerSubquery()
49+
{
50+
using (var session = OpenSession())
51+
{
52+
var clientId = "aa";
53+
session.Query<Entity>().Where(x =>
54+
x.List.Where(l => session.Query<Entity>().Any(s => s.Name == l.Name)).Select(l => l.Name)
55+
.Contains(clientId)).ToList();
56+
}
57+
}
58+
59+
[Test]
60+
public void ContainsOnEntity()
61+
{
62+
using (var session = OpenSession())
63+
{
64+
var client = session.Load<Child>(Guid.NewGuid());
65+
session.Query<Entity>().Where(x => x.List.Contains(client)).ToList();
66+
}
67+
}
68+
69+
[Test]
70+
public void ContainsOnName()
71+
{
72+
using (var session = OpenSession())
73+
{
74+
var client = "aaa";
75+
session.Query<Entity>().Where(x => x.List.Select(l => l.Name).Contains(client)).ToList();
76+
}
77+
}
78+
79+
[Test]
80+
public void ContainsOnComponent()
81+
{
82+
using (var session = OpenSession())
83+
{
84+
var client = new CompositeKey() { Id1 = 1, Id2 = 2 };
85+
session.Query<Entity>().Where(x => x.List.Select(l => l.Component).Contains(client)).ToList();
86+
}
87+
}
88+
}
89+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH3218
5+
{
6+
public class Entity
7+
{
8+
public virtual Guid Id { get; set; }
9+
public virtual string Name { get; set; }
10+
public virtual IList<Child> List { get; set; }
11+
}
12+
13+
public class Child
14+
{
15+
public virtual Guid Id { get; set; }
16+
public virtual string Name { get; set; }
17+
public virtual CompositeKey Component { get; set; }
18+
}
19+
20+
public class CompositeKey
21+
{
22+
public int Id1 { get; set; }
23+
public int Id2 { get; set; }
24+
25+
public override bool Equals(object obj)
26+
{
27+
var key = obj as CompositeKey;
28+
return key != null
29+
&& Id1 == key.Id1
30+
&& Id2 == key.Id2;
31+
}
32+
33+
public override int GetHashCode()
34+
{
35+
var hashCode = -1596524975;
36+
hashCode = hashCode * -1521134295 + Id1.GetHashCode();
37+
hashCode = hashCode * -1521134295 + Id2.GetHashCode();
38+
return hashCode;
39+
}
40+
}
41+
}

src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
using System;
2-
using System.Collections;
3-
using System.Collections.Generic;
1+
using System.Collections;
42
using System.Linq;
5-
using System.Linq.Expressions;
63
using NHibernate.Hql.Ast;
4+
using NHibernate.Hql.Ast.ANTLR;
75
using Remotion.Linq.Clauses.ResultOperators;
86

97
namespace NHibernate.Linq.Visitors.ResultOperatorProcessors
@@ -38,7 +36,7 @@ public void Process(ContainsResultOperator resultOperator, QueryModelVisitor que
3836
if (itemExpression is HqlParameter)
3937
{
4038
tree.AddWhereClause(tree.TreeBuilder.Equality(
41-
tree.TreeBuilder.Ident(GetFromAlias(tree.Root).AstNode.Text),
39+
GetSelectExpression(tree.Root),
4240
itemExpression));
4341
ProcessAny.Process(tree);
4442
}
@@ -54,9 +52,9 @@ private static HqlRange GetFromRangeClause(HqlTreeNode node)
5452
return node.NodesPreOrder.OfType<HqlRange>().First();
5553
}
5654

57-
private static HqlAlias GetFromAlias(HqlTreeNode node)
55+
private static HqlExpression GetSelectExpression(HqlTreeNode node)
5856
{
59-
return node.NodesPreOrder.Single(n => n is HqlRange).Children.Single(n => n is HqlAlias) as HqlAlias;
57+
return node.NodesPreOrder.First(x => x.AstNode.Type == HqlSqlWalker.SELECT).Children.Single() as HqlExpression;
6058
}
6159

6260
private static bool IsEmptyList(HqlParameter source, VisitorParameters parameters)

0 commit comments

Comments
 (0)