Skip to content

Commit d03e068

Browse files
authored
Merge branch '5.3.x' into RM2792
2 parents 71e90e3 + 15e4a73 commit d03e068

File tree

12 files changed

+117
-86
lines changed

12 files changed

+117
-86
lines changed

.github/workflows/NetCoreTests.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: .NET Core
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
db:
7+
strategy:
8+
fail-fast: false
9+
matrix:
10+
include:
11+
- DB: SqlServer2008
12+
CONNECTION_STRING: "Server=localhost;initial catalog=nhibernate;User Id=sa;Password=P@ssw0rd;packet size=4096;"
13+
- DB: PostgreSQL
14+
CONNECTION_STRING: "Host=localhost;Username=nhibernate;Password=nhibernate;Database=nhibernate;Enlist=true;"
15+
- DB: Firebird
16+
CONNECTION_STRING: "DataSource=localhost;Database=nhibernate;User=SYSDBA;Password=nhibernate;charset=utf8;"
17+
- DB: MySQL
18+
CONNECTION_STRING: "Server=localhost;Uid=root;Password=nhibernate;Database=nhibernate;Old Guids=True;"
19+
ALLOW_FAILURE: true
20+
- DB: SQLite
21+
runs-on: ubuntu-latest
22+
continue-on-error: ${{matrix.ALLOW_FAILURE == true}}
23+
env:
24+
LANG: en-US.UTF-8 #default POSIX locale doesn't support ignore case comparisons
25+
name: ${{matrix.DB}}
26+
27+
steps:
28+
- name: Set up SqlServer
29+
if: matrix.DB == 'SqlServer2008'
30+
run: |
31+
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssw0rd" -e "MSSQL_PID=Express" -p 1433:1433 -d --name sqlexpress microsoft/mssql-server-linux:latest;
32+
33+
- name: Set up MySQL
34+
if: matrix.DB == 'MySQL'
35+
run: |
36+
sudo service mysql stop
37+
docker run --name mysql -e MYSQL_ROOT_PASSWORD=nhibernate -e MYSQL_USER=nhibernate -e MYSQL_PASSWORD=nhibernate -e MYSQL_DATABASE=nhibernate -p 3306:3306 --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 -d mysql:5.7 mysqld --lower_case_table_names=1
38+
39+
- name: Set up PostgreSQL
40+
if: matrix.DB == 'PostgreSQL'
41+
run: |
42+
docker run -d -e POSTGRES_USER=nhibernate -e POSTGRES_PASSWORD=nhibernate -e POSTGRES_DB=nhibernate -p 5432:5432 postgres:13
43+
44+
- name: Set up Firebird
45+
if: matrix.DB == 'Firebird'
46+
run: |
47+
docker run --name firebird -e EnableWireCrypt=true -e FIREBIRD_USER=nhibernate -e FIREBIRD_PASSWORD=nhibernate -e ISC_PASSWORD=nhibernate -e FIREBIRD_DATABASE=nhibernate -p 3050:3050 -d jacobalberty/firebird:v3.0
48+
49+
- uses: actions/checkout@v2
50+
- name: Setup .NET
51+
uses: actions/[email protected]
52+
with:
53+
dotnet-version: 2.1.x
54+
55+
- name: Build and Test
56+
run: |
57+
pwsh -noprofile -command "& ./build.ps1 -TaskList Set-Configuration,Test -properties @{'Database' = '${{matrix.DB}}';'ConnectionString'='${{matrix.CONNECTION_STRING}}'}"

.travis.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.

build-common/NHibernate.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
<PropertyGroup>
55
<NhVersion Condition="'$(NhVersion)' == ''" >5.3</NhVersion>
6-
<VersionPatch Condition="'$(VersionPatch)' == ''">8</VersionPatch>
6+
<VersionPatch Condition="'$(VersionPatch)' == ''">9</VersionPatch>
77
<!-- Clear VersionSuffix for making release and set it to dev for making development builds -->
8-
<VersionSuffix Condition="'$(VersionSuffix)' == ''"></VersionSuffix>
8+
<VersionSuffix Condition="'$(VersionSuffix)' == ''">dev</VersionSuffix>
99

1010
<VersionPrefix Condition="'$(VersionPrefix)' == ''">$(NhVersion).$(VersionPatch)</VersionPrefix>
1111
<VersionSuffix Condition="'$(VersionSuffix)' != '' AND '$(BuildNumber)' != ''">$(VersionSuffix).$(BuildNumber)</VersionSuffix>

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99

1010

1111
using System;
12+
using System.Linq;
1213
using System.Text.RegularExpressions;
1314
using NHibernate.Cfg.MappingSchema;
1415
using NHibernate.Mapping.ByCode;
1516
using NHibernate.Test.Hql.EntityJoinHqlTestEntities;
1617
using NUnit.Framework;
18+
using NHibernate.Linq;
1719

1820
namespace NHibernate.Test.Hql
1921
{
@@ -287,6 +289,24 @@ public async Task NullableOneToOneFetchQueryIsNotAffected2Async()
287289
}
288290
}
289291

292+
[Test(Description = "GH-2772")]
293+
public async Task NullableEntityProjectionAsync()
294+
{
295+
using (var session = OpenSession())
296+
using (session.BeginTransaction())
297+
{
298+
var nullableOwner1 = new NullableOwner {Name = "1", ManyToOne = await (session.LoadAsync<OneToOneEntity>(Guid.NewGuid()))};
299+
var nullableOwner2 = new NullableOwner {Name = "2"};
300+
await (session.SaveAsync(nullableOwner1));
301+
await (session.SaveAsync(nullableOwner2));
302+
303+
var fullList = await (session.Query<NullableOwner>().Select(x => new {x.Name, ManyToOneId = (Guid?) x.ManyToOne.Id}).ToListAsync());
304+
var withValidManyToOneList = await (session.Query<NullableOwner>().Where(x => x.ManyToOne != null).Select(x => new {x.Name, ManyToOneId = (Guid?) x.ManyToOne.Id}).ToListAsync());
305+
Assert.That(fullList.Count, Is.EqualTo(2));
306+
Assert.That(withValidManyToOneList.Count, Is.EqualTo(0));
307+
}
308+
}
309+
290310
[Test]
291311
public async Task EntityJoinWithEntityComparisonInWithClausShouldNotAddJoinAsync()
292312
{

src/NHibernate.Test/Hql/EntityJoinHqlTest.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Linq;
23
using System.Text.RegularExpressions;
34
using NHibernate.Cfg.MappingSchema;
45
using NHibernate.Mapping.ByCode;
@@ -276,6 +277,24 @@ public void NullableOneToOneFetchQueryIsNotAffected2()
276277
}
277278
}
278279

280+
[Test(Description = "GH-2772")]
281+
public void NullableEntityProjection()
282+
{
283+
using (var session = OpenSession())
284+
using (session.BeginTransaction())
285+
{
286+
var nullableOwner1 = new NullableOwner {Name = "1", ManyToOne = session.Load<OneToOneEntity>(Guid.NewGuid())};
287+
var nullableOwner2 = new NullableOwner {Name = "2"};
288+
session.Save(nullableOwner1);
289+
session.Save(nullableOwner2);
290+
291+
var fullList = session.Query<NullableOwner>().Select(x => new {x.Name, ManyToOneId = (Guid?) x.ManyToOne.Id}).ToList();
292+
var withValidManyToOneList = session.Query<NullableOwner>().Where(x => x.ManyToOne != null).Select(x => new {x.Name, ManyToOneId = (Guid?) x.ManyToOne.Id}).ToList();
293+
Assert.That(fullList.Count, Is.EqualTo(2));
294+
Assert.That(withValidManyToOneList.Count, Is.EqualTo(0));
295+
}
296+
}
297+
279298
[Test]
280299
public void EntityJoinWithEntityComparisonInWithClausShouldNotAddJoin()
281300
{

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<PackageReference Include="NUnit" Version="3.12.0" />
6464
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
6565
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.1" />
66-
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="6.3.0" />
66+
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="6.6.0" />
6767
<PackageReference Include="Npgsql" Version="4.0.3" />
6868
</ItemGroup>
6969
<ItemGroup Condition="$(NhNetFx)">

src/NHibernate.Test/UtilityTest/SetSnapShotFixture.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ public void TestInitialization()
4949
Assert.That(sn.TryGetValue(null, out _), Is.True);
5050
}
5151

52+
[Test]
53+
public void TestDuplicates()
54+
{
55+
var list = new List<string> { "test1", "test1", "test2" };
56+
var sn = new SetSnapShot<string>(list);
57+
Assert.That(sn, Has.Count.EqualTo(2));
58+
Assert.That(sn.TryGetValue("test1", out _), Is.True);
59+
Assert.That(sn.TryGetValue("test2", out _), Is.True);
60+
}
61+
5262
[Test]
5363
public void TestCopyTo()
5464
{

src/NHibernate/Collection/Generic/SetHelpers/SetSnapShot.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public SetSnapShot(IEnumerable<T> collection)
3333
}
3434
else
3535
{
36-
_values.Add(item, item);
36+
_values[item] = item;
3737
}
3838
}
3939
}
@@ -70,7 +70,7 @@ public void Add(T item)
7070
return;
7171
}
7272

73-
_values.Add(item, item);
73+
_values[item] = item;
7474
}
7575

7676
public void Clear()

src/NHibernate/Driver/FirebirdClientDriver.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ public void ClearPool(string connectionString)
160160
using (var clearConnection = CreateConnection())
161161
{
162162
var connectionType = clearConnection.GetType();
163-
_clearPool = connectionType.GetMethod("ClearPool") ?? throw new InvalidOperationException("Unable to resolve ClearPool method.");
164-
_clearAllPools = connectionType.GetMethod("ClearAllPools") ?? throw new InvalidOperationException("Unable to resolve ClearAllPools method.");
163+
_clearPool = connectionType.GetMethod("ClearPool", new[] { connectionType }) ?? throw new InvalidOperationException("Unable to resolve ClearPool method.");
164+
_clearAllPools = connectionType.GetMethod("ClearAllPools", Array.Empty<System.Type>()) ?? throw new InvalidOperationException("Unable to resolve ClearAllPools method.");
165165
}
166166
}
167167

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string
389389
//For nullable entity comparisons we always need to add join (like not constrained one-to-one or not-found ignore associations)
390390
//NOTE: This fix is not fully correct. It doesn't work for comparisons with null (where e.OneToOneProp is null)
391391
// as by default implicit join is generated and to work propelry left join is required (see GH-2611)
392-
bool comparisonWithNullableEntity = false;
392+
bool comparisonWithNullableEntity = entityType.IsNullable && Walker.IsComparativeExpressionClause;
393393

394394
if ( IsDotNode( parent ) )
395395
{
@@ -398,7 +398,7 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string
398398
// entity's PK (because 'our' table would know the FK).
399399
parentAsDotNode = ( DotNode ) parent;
400400
property = parentAsDotNode._propertyName;
401-
joinIsNeeded = generateJoin && ((Walker.IsSelectStatement && entityType.IsNullable) || !IsReferenceToPrimaryKey( parentAsDotNode._propertyName, entityType ));
401+
joinIsNeeded = generateJoin && ((Walker.IsSelectStatement && comparisonWithNullableEntity) || !IsReferenceToPrimaryKey( parentAsDotNode._propertyName, entityType ));
402402
}
403403
else if ( ! Walker.IsSelectStatement )
404404
{
@@ -411,7 +411,6 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string
411411
}
412412
else
413413
{
414-
comparisonWithNullableEntity = (Walker.IsComparativeExpressionClause && entityType.IsNullable);
415414
joinIsNeeded = generateJoin || (Walker.IsInSelect && !Walker.IsInCase) || (Walker.IsInFrom && !Walker.IsComparativeExpressionClause)
416415
|| comparisonWithNullableEntity;
417416
}

src/NHibernate/Impl/SessionImpl.cs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,14 +1483,6 @@ public void Reconnect(DbConnection conn)
14831483
private string fetchProfile;
14841484
private IDisposable _context;
14851485

1486-
/// <summary>
1487-
/// Finalizer that ensures the object is correctly disposed of.
1488-
/// </summary>
1489-
~SessionImpl()
1490-
{
1491-
Dispose(false);
1492-
}
1493-
14941486
/// <summary>
14951487
/// Perform a soft (distributed transaction aware) close of the session
14961488
/// </summary>
@@ -1517,15 +1509,12 @@ public void Dispose()
15171509
_context?.Dispose();
15181510
}
15191511

1512+
//TODO: Get rid of isDisposing parameter. Finalizer is removed as not needed, so isDisposing is always true
15201513
/// <summary>
15211514
/// Takes care of freeing the managed and unmanaged resources that
15221515
/// this class is responsible for.
15231516
/// </summary>
15241517
/// <param name="isDisposing">Indicates if this Session is being Disposed of or Finalized.</param>
1525-
/// <remarks>
1526-
/// If this Session is being Finalized (<c>isDisposing==false</c>) then make sure not
1527-
/// to call any methods that could potentially bring this Session back to life.
1528-
/// </remarks>
15291518
private void Dispose(bool isDisposing)
15301519
{
15311520
using (BeginContext())
@@ -1546,8 +1535,6 @@ private void Dispose(bool isDisposing)
15461535
{
15471536
Close();
15481537
}
1549-
// nothing for Finalizer to do - so tell the GC to ignore it
1550-
GC.SuppressFinalize(this);
15511538
}
15521539

15531540
// free unmanaged resources here

src/NHibernate/Impl/StatelessSessionImpl.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -759,14 +759,6 @@ public IQueryOver<T, T> QueryOver<T>(Expression<Func<T>> alias) where T : class
759759
private bool _isAlreadyDisposed;
760760
private IDisposable _context;
761761

762-
/// <summary>
763-
/// Finalizer that ensures the object is correctly disposed of.
764-
/// </summary>
765-
~StatelessSessionImpl()
766-
{
767-
Dispose(false);
768-
}
769-
770762
///<summary>
771763
///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
772764
///</summary>
@@ -793,6 +785,7 @@ public void Dispose()
793785
}
794786
}
795787

788+
//TODO: Get rid of isDisposing parameter. Finalizer is removed as not needed, so isDisposing is always true
796789
protected void Dispose(bool isDisposing)
797790
{
798791
using (BeginContext())
@@ -811,9 +804,6 @@ protected void Dispose(bool isDisposing)
811804
{
812805
Close();
813806
}
814-
815-
// nothing for Finalizer to do - so tell the GC to ignore it
816-
GC.SuppressFinalize(this);
817807
}
818808

819809
// free unmanaged resources here

0 commit comments

Comments
 (0)