Skip to content

Commit 079cea4

Browse files
committed
ISessionImplementor.AutoFlushIfRequired
1 parent 9ff2997 commit 079cea4

File tree

10 files changed

+119
-27
lines changed

10 files changed

+119
-27
lines changed

src/NHibernate.Test/Async/Futures/LinqFutureFixture.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ public async Task FutureCombineCachedAndNonCachedQueriesAsync()
539539
public async Task FutureAutoFlushAsync()
540540
{
541541
using (var s = OpenSession())
542-
using (s.BeginTransaction())
542+
using (var tx = s.BeginTransaction())
543543
{
544544
s.FlushMode = FlushMode.Auto;
545545
var p1 = new Person
@@ -552,6 +552,8 @@ public async Task FutureAutoFlushAsync()
552552

553553
await (s.DeleteAsync(p1));
554554
var count = await (s.QueryOver<Person>().ToRowCountQuery().FutureValue<int>().GetValueAsync());
555+
await (tx.CommitAsync());
556+
555557
Assert.That(count, Is.EqualTo(0), "Session wasn't auto flushed.");
556558
}
557559
}

src/NHibernate.Test/Async/QueryTest/MultiCriteriaFixture.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,5 +474,32 @@ public async Task UsingManyParametersAndQueries_DoesNotCauseParameterNameCollisi
474474
}
475475
}
476476
}
477+
478+
//NH-2428 - Session.MultiCriteria and FlushMode.Auto inside transaction (GH865)
479+
[Test]
480+
public async Task MultiCriteriaAutoFlushAsync()
481+
{
482+
using (var s = OpenSession())
483+
using (var tx = s.BeginTransaction())
484+
{
485+
s.FlushMode = FlushMode.Auto;
486+
var p1 = new Item
487+
{
488+
Name = "Person name",
489+
Id = 15
490+
};
491+
await (s.SaveAsync(p1));
492+
await (s.FlushAsync());
493+
494+
await (s.DeleteAsync(p1));
495+
var multi = s.CreateMultiCriteria();
496+
multi.Add<int>(s.QueryOver<Item>().ToRowCountQuery());
497+
var count = (int) ((IList) (await (multi.ListAsync()))[0])[0];
498+
await (tx.CommitAsync());
499+
500+
Assert.That(count, Is.EqualTo(0), "Session wasn't auto flushed.");
501+
502+
}
503+
}
477504
}
478505
}

src/NHibernate.Test/Futures/LinqFutureFixture.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ public void FutureCombineCachedAndNonCachedQueries()
528528
public void FutureAutoFlush()
529529
{
530530
using (var s = OpenSession())
531-
using (s.BeginTransaction())
531+
using (var tx = s.BeginTransaction())
532532
{
533533
s.FlushMode = FlushMode.Auto;
534534
var p1 = new Person
@@ -541,6 +541,8 @@ public void FutureAutoFlush()
541541

542542
s.Delete(p1);
543543
var count = s.QueryOver<Person>().ToRowCountQuery().FutureValue<int>().Value;
544+
tx.Commit();
545+
544546
Assert.That(count, Is.EqualTo(0), "Session wasn't auto flushed.");
545547
}
546548
}

src/NHibernate.Test/QueryTest/MultiCriteriaFixture.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,5 +520,32 @@ public void UsingManyParametersAndQueries_DoesNotCauseParameterNameCollisions()
520520
}
521521
}
522522
}
523+
524+
//NH-2428 - Session.MultiCriteria and FlushMode.Auto inside transaction (GH865)
525+
[Test]
526+
public void MultiCriteriaAutoFlush()
527+
{
528+
using (var s = OpenSession())
529+
using (var tx = s.BeginTransaction())
530+
{
531+
s.FlushMode = FlushMode.Auto;
532+
var p1 = new Item
533+
{
534+
Name = "Person name",
535+
Id = 15
536+
};
537+
s.Save(p1);
538+
s.Flush();
539+
540+
s.Delete(p1);
541+
var multi = s.CreateMultiCriteria();
542+
multi.Add<int>(s.QueryOver<Item>().ToRowCountQuery());
543+
var count = (int) ((IList) multi.List()[0])[0];
544+
tx.Commit();
545+
546+
Assert.That(count, Is.EqualTo(0), "Session wasn't auto flushed.");
547+
548+
}
549+
}
523550
}
524551
}

src/NHibernate/Async/Engine/ISessionImplementor.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ namespace NHibernate.Engine
2828
{
2929
using System.Threading.Tasks;
3030
using System.Threading;
31+
internal static partial class SessionImplementorExtensions
32+
{
33+
34+
internal static async Task AutoFlushIfRequiredAsync(this ISessionImplementor implementor, ISet<string> querySpaces, CancellationToken cancellationToken)
35+
{
36+
cancellationToken.ThrowIfCancellationRequested();
37+
var autoFlushIfRequiredTask = (implementor as AbstractSessionImpl)?.AutoFlushIfRequiredAsync(querySpaces, cancellationToken);
38+
if (autoFlushIfRequiredTask != null)
39+
{
40+
await (autoFlushIfRequiredTask).ConfigureAwait(false);
41+
}
42+
}
43+
}
3144

3245
public partial interface ISessionImplementor
3346
{

src/NHibernate/Async/Impl/AbstractSessionImpl.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,30 @@ public virtual async Task<IList<T>> ListCustomQueryAsync<T>(ICustomQuery customQ
166166
public abstract Task<object> GetEntityUsingInterceptorAsync(EntityKey key, CancellationToken cancellationToken);
167167
public abstract Task<int> ExecuteNativeUpdateAsync(NativeSQLQuerySpecification specification, QueryParameters queryParameters, CancellationToken cancellationToken);
168168

169+
//6.0 TODO: Make abstract
170+
/// <summary>
171+
/// detect in-memory changes, determine if the changes are to tables
172+
/// named in the query and, if so, complete execution the flush
173+
/// </summary>
174+
/// <param name="querySpaces"></param>
175+
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
176+
/// <returns>Returns true if flush was executed</returns>
177+
public virtual Task<bool> AutoFlushIfRequiredAsync(ISet<string> querySpaces, CancellationToken cancellationToken)
178+
{
179+
if (cancellationToken.IsCancellationRequested)
180+
{
181+
return Task.FromCanceled<bool>(cancellationToken);
182+
}
183+
try
184+
{
185+
return Task.FromResult<bool>(AutoFlushIfRequired(querySpaces));
186+
}
187+
catch (Exception ex)
188+
{
189+
return Task.FromException<bool>(ex);
190+
}
191+
}
192+
169193
public abstract Task FlushAsync(CancellationToken cancellationToken);
170194

171195
#endregion

src/NHibernate/Async/Impl/SessionImpl.cs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,6 @@ namespace NHibernate.Impl
3737
{
3838
using System.Threading.Tasks;
3939
using System.Threading;
40-
internal static partial class SessionImplExtensions
41-
{
42-
internal static async Task AutoFlushIfRequiredAsync(this ISessionImplementor implementor, ISet<string> querySpaces, CancellationToken cancellationToken)
43-
{
44-
cancellationToken.ThrowIfCancellationRequested();
45-
var autoFlushIfRequiredTask = (implementor as SessionImpl)?.AutoFlushIfRequiredAsync(querySpaces, cancellationToken);
46-
if (autoFlushIfRequiredTask != null)
47-
{
48-
await (autoFlushIfRequiredTask).ConfigureAwait(false);
49-
}
50-
}
51-
}
5240
public sealed partial class SessionImpl : AbstractSessionImpl, IEventSource, ISerializable, IDeserializationCallback
5341
{
5442

@@ -691,8 +679,8 @@ public override async Task<object> GetEntityUsingInterceptorAsync(EntityKey key,
691679
/// </summary>
692680
/// <param name="querySpaces"></param>
693681
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
694-
/// <returns></returns>
695-
internal async Task<bool> AutoFlushIfRequiredAsync(ISet<string> querySpaces, CancellationToken cancellationToken)
682+
/// <returns>Returns true if flush was executed</returns>
683+
public override async Task<bool> AutoFlushIfRequiredAsync(ISet<string> querySpaces, CancellationToken cancellationToken)
696684
{
697685
cancellationToken.ThrowIfCancellationRequested();
698686
using (BeginProcess())

src/NHibernate/Engine/ISessionImplementor.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
namespace NHibernate.Engine
1818
{
1919
// 6.0 TODO: Convert to interface methods
20-
internal static class SessionImplementorExtensions
20+
internal static partial class SessionImplementorExtensions
2121
{
2222
internal static IDisposable BeginContext(this ISessionImplementor session)
2323
{
@@ -40,6 +40,11 @@ internal static IMultiAnyQueryBatch GetFutureMultiBatch(this ISessionImplementor
4040
{
4141
return (session as AbstractSessionImpl)?.FutureMultiBatch;
4242
}
43+
44+
internal static void AutoFlushIfRequired(this ISessionImplementor implementor, ISet<string> querySpaces)
45+
{
46+
(implementor as AbstractSessionImpl)?.AutoFlushIfRequired(querySpaces);
47+
}
4348
}
4449

4550
/// <summary>

src/NHibernate/Impl/AbstractSessionImpl.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,18 @@ public virtual FlushMode FlushMode
301301
set => _flushMode = value;
302302
}
303303

304+
//6.0 TODO: Make abstract
305+
/// <summary>
306+
/// detect in-memory changes, determine if the changes are to tables
307+
/// named in the query and, if so, complete execution the flush
308+
/// </summary>
309+
/// <param name="querySpaces"></param>
310+
/// <returns>Returns true if flush was executed</returns>
311+
public virtual bool AutoFlushIfRequired(ISet<string> querySpaces)
312+
{
313+
return false;
314+
}
315+
304316
public virtual IQuery GetNamedQuery(string queryName)
305317
{
306318
using (BeginProcess())

src/NHibernate/Impl/SessionImpl.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,6 @@
2525

2626
namespace NHibernate.Impl
2727
{
28-
internal static partial class SessionImplExtensions
29-
{
30-
internal static void AutoFlushIfRequired(this ISessionImplementor implementor, ISet<string> querySpaces)
31-
{
32-
(implementor as SessionImpl)?.AutoFlushIfRequired(querySpaces);
33-
}
34-
}
35-
3628
/// <summary>
3729
/// Concrete implementation of an <see cref="ISession" />, also the central, organizing component
3830
/// of NHibernate's internal implementation.
@@ -1044,8 +1036,8 @@ public override IPersistenceContext PersistenceContext
10441036
/// named in the query and, if so, complete execution the flush
10451037
/// </summary>
10461038
/// <param name="querySpaces"></param>
1047-
/// <returns></returns>
1048-
internal bool AutoFlushIfRequired(ISet<string> querySpaces)
1039+
/// <returns>Returns true if flush was executed</returns>
1040+
public override bool AutoFlushIfRequired(ISet<string> querySpaces)
10491041
{
10501042
using (BeginProcess())
10511043
{

0 commit comments

Comments
 (0)