Skip to content

Commit f41a800

Browse files
Merge 5.4.2 into master
2 parents a98192d + cddbac1 commit f41a800

25 files changed

+496
-44
lines changed

releasenotes.txt

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1-
Build 5.4.1
1+
Build 5.4.2
2+
=============================
3+
4+
Release notes - NHibernate - Version 5.4.2
5+
6+
6 issues were resolved in this release.
7+
8+
** Bug
9+
10+
* #3274 Improve LINQ Contains subquery parameter detection
11+
* #3271 LINQ subqueries wrongly altered by SelectClauseVisitor
12+
* #3263 Wrong alias in Where clause if using Fetch and scalar Select
13+
* #3239 Incorrect SQL generated fetching many-to-many with subclasses
14+
15+
** New Feature
16+
17+
* #3251 MappingByCode: Support backfield property access
18+
19+
** Task
20+
21+
* #3281 Merge 5.3.16 in 5.4.x
22+
* #3277 Release 5.4.2
23+
24+
25+
Build 5.4.1
226
=============================
327

428
Release notes - NHibernate - Version 5.4.1
529

6-
4 issues were resolved in this release.
30+
5 issues were resolved in this release.
731

832
** Bug
933

@@ -14,6 +38,7 @@ Release notes - NHibernate - Version 5.4.1
1438
** Task
1539

1640
* #3232 Release 5.4.1
41+
* #3227 Merge 5.3.15 in 5.4.x
1742

1843
As part of releasing 5.4.1, a missing 5.4.0 possible breaking change has been added, about
1944
one-to-one associations and optimistic locking. See 5.4.0 possible breaking changes.
@@ -209,6 +234,23 @@ Release notes - NHibernate - Version 5.4.0
209234
* #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
210235

211236

237+
Build 5.3.16
238+
=============================
239+
240+
Release notes - NHibernate - Version 5.3.16
241+
242+
3 issues were resolved in this release.
243+
244+
** Bug
245+
246+
* #3269 "Or" clause in a "where" condition returns a wrong result with not-found-ignore
247+
* #3210 Wrong name value for L2 read-only cache warning on mutable
248+
249+
** Task
250+
251+
* #3276 Release 5.3.16
252+
253+
212254
Build 5.3.15
213255
=============================
214256

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,15 @@ from x2 in session.Query<NullableOwner>()
358358
//GH-2988
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());
361+
//GH-3269
362+
var invalidId = Guid.NewGuid();
363+
var withInvalidOrValid = await (session.Query<NullableOwner>().Where(x => x.OneToOne.Id == invalidId || x.ManyToOne.Id == validManyToOne.Id).ToListAsync());
364+
var withInvalidOrNull = await (session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == invalidId || x.OneToOne == null).ToListAsync());
365+
var withInvalidOrNotNull = await (session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == invalidId || x.OneToOne != null).ToListAsync());
366+
367+
Assert.That(withInvalidOrValid.Count, Is.EqualTo(1));
368+
Assert.That(withInvalidOrNull.Count, Is.EqualTo(2));
369+
Assert.That(withInvalidOrNotNull.Count, Is.EqualTo(0));
361370

362371
//GH-3185
363372
var mixImplicitAndLeftJoinList = await (session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == validManyToOne.Id && x.OneToOne == null).ToListAsync());

src/NHibernate.Test/Async/Linq/WhereTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System.Linq;
1616
using System.Linq.Expressions;
1717
using log4net.Core;
18+
using NHibernate.Dialect;
1819
using NHibernate.Engine.Query;
1920
using NHibernate.Linq;
2021
using NHibernate.DomainModel.Northwind.Entities;
@@ -670,6 +671,38 @@ where sheet.Users.Contains(user)
670671
Assert.That(query.Count, Is.EqualTo(2));
671672
}
672673

674+
[Test]
675+
public async Task TimesheetsWithEnumerableContainsOnSelectAsync()
676+
{
677+
if (Dialect is MsSqlCeDialect)
678+
Assert.Ignore("Dialect is not supported");
679+
680+
var value = (EnumStoredAsInt32) 1000;
681+
var query = await ((from sheet in db.Timesheets
682+
where sheet.Users.Select(x => x.NullableEnum2 ?? value).Contains(value)
683+
select sheet).ToListAsync());
684+
685+
Assert.That(query.Count, Is.EqualTo(1));
686+
}
687+
688+
[Test]
689+
public async Task ContainsSubqueryWithCoalesceStringEnumSelectAsync()
690+
{
691+
if (Dialect is MsSqlCeDialect || Dialect is SQLiteDialect)
692+
Assert.Ignore("Dialect is not supported");
693+
694+
var results =
695+
await (db.Timesheets.Where(
696+
o =>
697+
o.Users
698+
.Where(u => u.Id != 0.MappedAs(NHibernateUtil.Int32))
699+
.Select(u => u.Name == u.Name ? u.Enum1 : u.NullableEnum1.Value)
700+
.Contains(EnumStoredAsString.Small))
701+
.ToListAsync());
702+
703+
Assert.That(results.Count, Is.EqualTo(1));
704+
}
705+
673706
[Test]
674707
public async Task SearchOnObjectTypeWithExtensionMethodAsync()
675708
{
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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.Linq;
12+
using NHibernate.Linq;
13+
using NUnit.Framework;
14+
15+
namespace NHibernate.Test.NHSpecificTest.GH3263
16+
{
17+
using System.Threading.Tasks;
18+
[TestFixture]
19+
public class ReuseFetchJoinFixtureAsync : BugTestCase
20+
{
21+
protected override void OnSetUp()
22+
{
23+
using var s = OpenSession();
24+
using var t = s.BeginTransaction();
25+
var em = new Employee() { Name = "x", OptionalInfo = new OptionalInfo() };
26+
em.OptionalInfo.Employee = em;
27+
s.Save(em);
28+
t.Commit();
29+
}
30+
protected override void OnTearDown()
31+
{
32+
using var session = OpenSession();
33+
using var transaction = session.BeginTransaction();
34+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
35+
36+
transaction.Commit();
37+
}
38+
39+
[Test]
40+
public async Task ReuseJoinScalarSelectAsync()
41+
{
42+
using var session = OpenSession();
43+
await (session.Query<Employee>()
44+
.Fetch(x => x.OptionalInfo)
45+
.Where(x => x.OptionalInfo != null)
46+
.Select(x => new { x.OptionalInfo.Age })
47+
.ToListAsync());
48+
}
49+
50+
[Test]
51+
public async Task ReuseJoinScalarSelectHqlAsync()
52+
{
53+
using var session = OpenSession();
54+
await (session.CreateQuery(
55+
"select x.OptionalInfo.Age " +
56+
"from Employee x " +
57+
"fetch x.OptionalInfo " +
58+
"where x.OptionalInfo != null ").ListAsync());
59+
60+
}
61+
62+
[Test]
63+
public async Task ReuseJoinScalarSelectHql2Async()
64+
{
65+
using var session = OpenSession();
66+
await (session.CreateQuery(
67+
"select x.OptionalInfo.Age " +
68+
"from Employee x " +
69+
"join fetch x.OptionalInfo o " +
70+
"where o != null ").ListAsync());
71+
}
72+
73+
[Test]
74+
public async Task ReuseJoinScalarSelectHql3Async()
75+
{
76+
using var session = OpenSession();
77+
await (session.CreateQuery(
78+
"select x.OptionalInfo.Age from Employee x " +
79+
"join fetch x.OptionalInfo " +
80+
"where x.OptionalInfo != null ").ListAsync());
81+
}
82+
83+
[Test]
84+
public async Task ReuseJoinEntityAndScalarSelectAsync()
85+
{
86+
using var session = OpenSession();
87+
using var sqlLog = new SqlLogSpy();
88+
89+
var x = await (session.Query<Employee>()
90+
.Fetch(x => x.OptionalInfo)
91+
.Where(x => x.OptionalInfo != null)
92+
.Select(x => new { x, x.OptionalInfo.Age })
93+
.FirstAsync());
94+
95+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1));
96+
Assert.That(NHibernateUtil.IsInitialized(x.x.OptionalInfo), Is.True);
97+
}
98+
}
99+
}

src/NHibernate.Test/Async/NHSpecificTest/NH2174/Fixture.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ protected override void OnSetUp()
2525
{
2626
var doc = new Document {Id_Base = 1, Id_Doc = 2};
2727
session.Save(doc);
28-
session.Save(new DocumentDetailDocument {Id_Base = 1, Id_Doc = 2, Id_Item = 1, ReferencedDocument = doc});
28+
var detail = new DocumentDetailDocument {Id_Base = 1, Id_Doc = 2, Id_Item = 1, ReferencedDocument = doc};
29+
session.Save(detail);
2930

31+
doc.RefferedDetailsManyToMany.Add(detail);
3032
transaction.Commit();
3133
}
3234
}
@@ -53,6 +55,14 @@ public async Task LinqFetchAsync()
5355
}
5456
}
5557

58+
[Test(Description = "GH-3239")]
59+
public async Task LinqFetchManyToManyAsync()
60+
{
61+
using var session = OpenSession();
62+
var result = await (session.Query<Document>().Fetch(x => x.RefferedDetailsManyToMany).FirstAsync());
63+
Assert.That(result.RefferedDetailsManyToMany, Has.Count.EqualTo(1));
64+
}
65+
5666
[Test]
5767
public async Task QueryOverFetchAsync()
5868
{
@@ -63,6 +73,14 @@ public async Task QueryOverFetchAsync()
6373
}
6474
}
6575

76+
[Test(Description = "GH-3239")]
77+
public async Task QueryOverFetchManyToManyAsync()
78+
{
79+
using var session = OpenSession();
80+
var result = await (session.QueryOver<Document>().Fetch(SelectMode.Fetch, x => x.RefferedDetailsManyToMany).SingleOrDefaultAsync());
81+
Assert.That(result.RefferedDetailsManyToMany, Has.Count.EqualTo(1));
82+
}
83+
6684
[Test]
6785
public async Task LazyLoadAsync()
6886
{
@@ -73,5 +91,13 @@ public async Task LazyLoadAsync()
7391
Assert.That(result.RefferedDetails.Count, Is.EqualTo(1));
7492
}
7593
}
94+
95+
[Test]
96+
public async Task LazyLoadManyToManyAsync()
97+
{
98+
using var session = OpenSession();
99+
var result = await (session.Query<Document>().FirstAsync());
100+
Assert.That(result.RefferedDetailsManyToMany.Count, Is.EqualTo(1));
101+
}
76102
}
77103
}

src/NHibernate.Test/Hql/EntityJoinHqlTest.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,15 @@ from x2 in session.Query<NullableOwner>()
346346
//GH-2988
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();
349+
//GH-3269
350+
var invalidId = Guid.NewGuid();
351+
var withInvalidOrValid = session.Query<NullableOwner>().Where(x => x.OneToOne.Id == invalidId || x.ManyToOne.Id == validManyToOne.Id).ToList();
352+
var withInvalidOrNull = session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == invalidId || x.OneToOne == null).ToList();
353+
var withInvalidOrNotNull = session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == invalidId || x.OneToOne != null).ToList();
354+
355+
Assert.That(withInvalidOrValid.Count, Is.EqualTo(1));
356+
Assert.That(withInvalidOrNull.Count, Is.EqualTo(2));
357+
Assert.That(withInvalidOrNotNull.Count, Is.EqualTo(0));
349358

350359
//GH-3185
351360
var mixImplicitAndLeftJoinList = session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == validManyToOne.Id && x.OneToOne == null).ToList();

src/NHibernate.Test/Linq/WhereTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Linq.Expressions;
77
using log4net.Core;
8+
using NHibernate.Dialect;
89
using NHibernate.Engine.Query;
910
using NHibernate.Linq;
1011
using NHibernate.DomainModel.Northwind.Entities;
@@ -671,6 +672,38 @@ where sheet.Users.Contains(user)
671672
Assert.That(query.Count, Is.EqualTo(2));
672673
}
673674

675+
[Test]
676+
public void TimesheetsWithEnumerableContainsOnSelect()
677+
{
678+
if (Dialect is MsSqlCeDialect)
679+
Assert.Ignore("Dialect is not supported");
680+
681+
var value = (EnumStoredAsInt32) 1000;
682+
var query = (from sheet in db.Timesheets
683+
where sheet.Users.Select(x => x.NullableEnum2 ?? value).Contains(value)
684+
select sheet).ToList();
685+
686+
Assert.That(query.Count, Is.EqualTo(1));
687+
}
688+
689+
[Test]
690+
public void ContainsSubqueryWithCoalesceStringEnumSelect()
691+
{
692+
if (Dialect is MsSqlCeDialect || Dialect is SQLiteDialect)
693+
Assert.Ignore("Dialect is not supported");
694+
695+
var results =
696+
db.Timesheets.Where(
697+
o =>
698+
o.Users
699+
.Where(u => u.Id != 0.MappedAs(NHibernateUtil.Int32))
700+
.Select(u => u.Name == u.Name ? u.Enum1 : u.NullableEnum1.Value)
701+
.Contains(EnumStoredAsString.Small))
702+
.ToList();
703+
704+
Assert.That(results.Count, Is.EqualTo(1));
705+
}
706+
674707
[Test]
675708
public void SearchOnObjectTypeWithExtensionMethod()
676709
{

src/NHibernate.Test/MappingByCode/ExplicitMappingTests/AllPropertiesRegistrationTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,20 @@ public void WhenMapPropertiesInTheBaseJumpedClassUsingMemberNameThenMapInInherit
188188
Assert.That(hbmClass.Properties.Select(p => p.Access).All(a => a.StartsWith("field.")), Is.True);
189189
}
190190

191+
[Test]
192+
public void BackfieldAccessPropertyMapping()
193+
{
194+
var mapper = new ModelMapper();
195+
mapper.Class<MyClass>(mc =>
196+
{
197+
mc.Id(x => x.Id, m => m.Access(Accessor.Backfield));
198+
});
199+
200+
HbmMapping mappings = mapper.CompileMappingForAllExplicitlyAddedEntities();
201+
HbmClass hbmClass = mappings.RootClasses[0];
202+
Assert.That(hbmClass.Id.access, Is.EqualTo("backfield"));
203+
}
204+
191205
[Test]
192206
public void WhenMapBagWithWrongElementTypeThenThrows()
193207
{
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace NHibernate.Test.NHSpecificTest.GH3263
2+
{
3+
public class Employee
4+
{
5+
public virtual int EmployeeId { get; set; }
6+
public virtual string Name { get; set; }
7+
public virtual OptionalInfo OptionalInfo { get; set; }
8+
}
9+
10+
public class OptionalInfo
11+
{
12+
public virtual int EmployeeId { get; set; }
13+
public virtual int Age { get; set; }
14+
public virtual Employee Employee { get; set; }
15+
}
16+
}

0 commit comments

Comments
 (0)