Skip to content

Commit e85c935

Browse files
Merge 5.3.11
Discarded changes: - UpdateTimestampsCache.cs, see #3019 - packages.csproj, see #2984
2 parents 502d243 + 211891f commit e85c935

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1036
-113
lines changed

doc/reference/modules/configuration.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,26 @@ var session = sessions.OpenSession(conn);
610610
</para>
611611
</entry>
612612
</row>
613+
<row>
614+
<entry>
615+
<literal>cache.read_write_lock_factory</literal>
616+
</entry>
617+
<entry>
618+
Specify the cache lock factory to use for read-write cache regions.
619+
Defaults to the built-in <literal>async</literal> cache lock factory.
620+
<para>
621+
<emphasis role="strong">eg.</emphasis>
622+
<literal>async</literal>, or <literal>sync</literal>, or <literal>classname.of.CacheLockFactory, assembly</literal> with custom implementation of <literal>ICacheReadWriteLockFactory</literal>
623+
</para>
624+
<para>
625+
<literal>async</literal> uses a single writer multiple readers locking mechanism supporting asynchronous operations.
626+
</para>
627+
<para>
628+
<literal>sync</literal> uses a single access locking mechanism which will throw on asynchronous
629+
operations but may have better performances than the <literal>async</literal> provider for applications using the .Net Framework (4.8 and below).
630+
</para>
631+
</entry>
632+
</row>
613633
<row>
614634
<entry>
615635
<literal>cache.region_prefix</literal>

releasenotes.txt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,29 @@
1-
Build 5.3.10
1+
Build 5.3.11
2+
=============================
3+
4+
Release notes - NHibernate - Version 5.3.11
5+
6+
12 issues were resolved in this release.
7+
8+
** Bug
9+
10+
* #3005 LINQ: Casting from object to TimeSpan throws
11+
* #2988 Query issues when using not-found='ignore' in entity mapping
12+
* #2965 Fix possible issue with logging for Linq Readonly tests
13+
* #2963 Time is incompatible with bigint for TimeAsTimeSpanType
14+
* #2937 NRE in linq processing of custom components
15+
* #2928 Session.Refresh when entity is IFieldInterceptorAccessor throws a MappingException
16+
* #2904 SQL query result not retrieved from second level cache
17+
* #2876 Schema validation not working with NpgSql v5
18+
* #2862 NHibernate AsyncReaderWriterLock stalls under load
19+
* #2727 The session.Load(obj, id) overload can't handle proxies
20+
21+
** Task
22+
23+
* #3019 Release 5.3.11
24+
* #2984 Bump AsyncGenerator to 0.18.3 for 5.3 branch with fix for .net 6
25+
26+
Build 5.3.10
227
=============================
328

429
Release notes - NHibernate - Version 5.3.10

src/AsyncGenerator.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@
226226
- conversion: Ignore
227227
anyBaseTypeRule: IsTestCase
228228
executionPhase: PostProviders
229+
- conversion: Ignore
230+
name: SyncOnlyCacheFixture
229231
ignoreDocuments:
230232
- filePathEndsWith: Linq/MathTests.cs
231233
- filePathEndsWith: Linq/ExpressionSessionLeakTest.cs

src/NHibernate.Test/Async/CacheTest/CacheFixture.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,22 @@ namespace NHibernate.Test.CacheTest
1919
{
2020
using System.Threading.Tasks;
2121
[TestFixture]
22-
public class CacheFixtureAsync
22+
public class CacheFixtureAsync: TestCase
2323
{
2424
[Test]
2525
public async Task TestSimpleCacheAsync()
2626
{
2727
await (DoTestCacheAsync(new HashtableCacheProvider()));
2828
}
2929

30-
private CacheKey CreateCacheKey(string text)
30+
protected CacheKey CreateCacheKey(string text)
3131
{
3232
return new CacheKey(text, NHibernateUtil.String, "Foo", null, null);
3333
}
3434

3535
public async Task DoTestCacheAsync(ICacheProvider cacheProvider, CancellationToken cancellationToken = default(CancellationToken))
3636
{
37-
var cache = cacheProvider.BuildCache(typeof(String).FullName, new Dictionary<string, string>());
37+
var cache = (CacheBase) cacheProvider.BuildCache(typeof(String).FullName, new Dictionary<string, string>());
3838

3939
long longBefore = Timestamper.Next();
4040

@@ -44,8 +44,7 @@ private CacheKey CreateCacheKey(string text)
4444

4545
await (Task.Delay(15, cancellationToken));
4646

47-
ICacheConcurrencyStrategy ccs = new ReadWriteCache();
48-
ccs.Cache = cache;
47+
ICacheConcurrencyStrategy ccs = CreateCache(cache);
4948

5049
// cache something
5150
CacheKey fooKey = CreateCacheKey("foo");
@@ -155,12 +154,17 @@ private CacheKey CreateCacheKey(string text)
155154
public async Task MinValueTimestampAsync()
156155
{
157156
var cache = new HashtableCacheProvider().BuildCache("region", new Dictionary<string, string>());
158-
ICacheConcurrencyStrategy strategy = new ReadWriteCache();
159-
strategy.Cache = cache;
160157

161-
await (DoTestMinValueTimestampOnStrategyAsync(cache, new ReadWriteCache()));
162-
await (DoTestMinValueTimestampOnStrategyAsync(cache, new NonstrictReadWriteCache()));
163-
await (DoTestMinValueTimestampOnStrategyAsync(cache, new ReadOnlyCache()));
158+
await (DoTestMinValueTimestampOnStrategyAsync(cache, CreateCache(cache)));
159+
await (DoTestMinValueTimestampOnStrategyAsync(cache, CreateCache(cache, CacheFactory.NonstrictReadWrite)));
160+
await (DoTestMinValueTimestampOnStrategyAsync(cache, CreateCache(cache, CacheFactory.ReadOnly)));
164161
}
162+
163+
protected virtual ICacheConcurrencyStrategy CreateCache(CacheBase cache, string strategy = CacheFactory.ReadWrite)
164+
{
165+
return CacheFactory.CreateCache(strategy, cache, Sfi.Settings);
166+
}
167+
168+
protected override string[] Mappings => Array.Empty<string>();
165169
}
166170
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,23 @@ public async Task NullableEntityProjectionAsync()
349349
from x2 in session.Query<NullableOwner>()
350350
where x == x2 && x.ManyToOne == null && x.OneToOne.Name == null
351351
select x2).ToListAsync());
352+
353+
var validManyToOne = new OneToOneEntity{Name = "valid"};
354+
await (session.SaveAsync(validManyToOne));
355+
nullableOwner2.ManyToOne = validManyToOne;
356+
await (session.FlushAsync());
357+
358+
//GH-2988
359+
var withNullOrValidList = await (session.Query<NullableOwner>().Where(x => x.ManyToOne.Id == validManyToOne.Id || x.ManyToOne == null).ToListAsync());
360+
var withNullOrValidList2 = await (session.Query<NullableOwner>().Where(x => x.ManyToOne == null || x.ManyToOne.Id == validManyToOne.Id).ToListAsync());
361+
352362
Assert.That(fullList.Count, Is.EqualTo(2));
353363
Assert.That(withValidManyToOneList.Count, Is.EqualTo(0));
354364
Assert.That(withValidManyToOneList2.Count, Is.EqualTo(0));
355365
Assert.That(withNullManyToOneList.Count, Is.EqualTo(2));
356366
Assert.That(withNullManyToOneJoinedList.Count, Is.EqualTo(2));
367+
Assert.That(withNullOrValidList.Count, Is.EqualTo(2));
368+
Assert.That(withNullOrValidList2.Count, Is.EqualTo(2));
357369
}
358370
}
359371

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
//------------------------------------------------------------------------------
99

1010

11+
using System;
1112
using System.Collections.ObjectModel;
1213
using System.Linq;
1314
using System.Linq.Expressions;
1415
using System.Reflection;
1516
using System.Text.RegularExpressions;
16-
using NHibernate.Cfg;
1717
using NHibernate.DomainModel.Northwind.Entities;
1818
using NHibernate.Hql.Ast;
1919
using NHibernate.Linq.Functions;
@@ -42,6 +42,18 @@ public async Task CanUseObjectEqualsAsync()
4242
Assert.That(users.All(c => c.NullableEnum1 == EnumStoredAsString.Medium), Is.True);
4343
}
4444

45+
[Test(Description = "GH-2963")]
46+
public async Task CanUseComparisonWithExtensionOnMappedPropertyAsync()
47+
{
48+
if (!TestDialect.SupportsTime)
49+
{
50+
Assert.Ignore("Time type is not supported");
51+
}
52+
53+
var time = DateTime.UtcNow.GetTime();
54+
await (db.Users.Where(u => u.RegisteredAt.GetTime() > time).Select(u => u.Id).ToListAsync());
55+
}
56+
4557
[Test]
4658
public async Task CanUseMyCustomExtensionAsync()
4759
{
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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 NHibernate.Cfg.MappingSchema;
13+
using NHibernate.Mapping.ByCode;
14+
using NUnit.Framework;
15+
16+
namespace NHibernate.Test.NHSpecificTest.GH2727
17+
{
18+
using System.Threading.Tasks;
19+
/// <summary>
20+
/// Fixture using 'by code' mappings
21+
/// </summary>
22+
[TestFixture]
23+
public class LazyPropByCodeFixtureAsync : TestCaseMappingByCode
24+
{
25+
private Guid id1;
26+
private Guid id2;
27+
28+
protected override HbmMapping GetMappings()
29+
{
30+
var mapper = new ModelMapper();
31+
mapper.Class<Entity>(
32+
rc =>
33+
{
34+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
35+
rc.Property(x => x.Name);
36+
rc.Property(x => x.LazyProp, m => m.Lazy(true));
37+
});
38+
39+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
40+
}
41+
42+
protected override void OnSetUp()
43+
{
44+
using (var session = OpenSession())
45+
using (var transaction = session.BeginTransaction())
46+
{
47+
var e1 = new Entity { Name = "Bob" };
48+
session.Save(e1);
49+
50+
var e2 = new Entity { Name = "Sally" };
51+
session.Save(e2);
52+
53+
transaction.Commit();
54+
id1 = e1.Id;
55+
id2 = e2.Id;
56+
}
57+
}
58+
59+
protected override void OnTearDown()
60+
{
61+
using (var session = OpenSession())
62+
using (var transaction = session.BeginTransaction())
63+
{
64+
// The HQL delete does all the job inside the database without loading the entities, but it does
65+
// not handle delete order for avoiding violating constraints if any. Use
66+
// session.Delete("from System.Object");
67+
// instead if in need of having NHbernate ordering the deletes, but this will cause
68+
// loading the entities in the session.
69+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
70+
71+
transaction.Commit();
72+
}
73+
}
74+
75+
[Test]
76+
public async Task CanLoadUsingInstanceAsync()
77+
{
78+
using (var s = OpenSession())
79+
{
80+
var e1 = await (s.LoadAsync<Entity>(id1));
81+
await (s.LoadAsync(e1, id2));
82+
}
83+
}
84+
85+
[Test(Description = "GH-2928")]
86+
public async Task CanSessionRefreshEntityWithLazyPropertiesAsync()
87+
{
88+
using (var s = OpenSession())
89+
{
90+
var e1 = await (s.GetAsync<Entity>(id1));
91+
await (s.RefreshAsync(e1));
92+
s.Clear();
93+
await (s.RefreshAsync(e1));
94+
}
95+
}
96+
}
97+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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.GH3005
19+
{
20+
using System.Threading.Tasks;
21+
[TestFixture]
22+
public class ByCodeFixtureAsync : TestCaseMappingByCode
23+
{
24+
protected override HbmMapping GetMappings()
25+
{
26+
var mapper = new ModelMapper();
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.Property(x => x.Duration);
32+
});
33+
34+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
35+
}
36+
37+
protected override void OnSetUp()
38+
{
39+
using (var session = OpenSession())
40+
using (var transaction = session.BeginTransaction())
41+
{
42+
var e1 = new Entity { Name = "Bob", Duration = TimeSpan.FromMinutes(1) };
43+
session.Save(e1);
44+
45+
transaction.Commit();
46+
}
47+
}
48+
49+
protected override void OnTearDown()
50+
{
51+
using (var session = OpenSession())
52+
using (var transaction = session.BeginTransaction())
53+
{
54+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
55+
56+
transaction.Commit();
57+
}
58+
}
59+
60+
[Test]
61+
public async Task CanCastFromObjectAsync()
62+
{
63+
using (var session = OpenSession())
64+
{
65+
var result = await (session.Query<Entity>().Select(x => (TimeSpan)(object)x.Duration).FirstOrDefaultAsync());
66+
67+
Assert.That(result, Is.EqualTo(TimeSpan.FromMinutes(1)));
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)