Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f5a7a1f

Browse files
wvoptcsharper2010
andauthored
Fix version update on dirty collection with another property having optimistic-lock false (#3632)
Co-authored-by: CSharper2010 <csharper2010@googlemail.com>
1 parent 0c9e442 commit f5a7a1f

File tree

6 files changed

+36
-25
lines changed

6 files changed

+36
-25
lines changed

‎src/NHibernate.Test/Async/VersionTest/Db/DbVersionFixture.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public async System.Threading.Tasks.Task CollectionVersionAsync()
5252
admin = await (s.GetAsync<Group>(admin.Id));
5353
guy.Groups.Add(admin);
5454
admin.Users.Add(guy);
55+
guy.NoOptimisticLock = "changed";
5556
await (t.CommitAsync());
5657
s.Close();
5758

‎src/NHibernate.Test/VersionTest/Db/DbVersionFixture.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public void CollectionVersion()
4242
admin = s.Get<Group>(admin.Id);
4343
guy.Groups.Add(admin);
4444
admin.Users.Add(guy);
45+
guy.NoOptimisticLock = "changed";
4546
t.Commit();
4647
s.Close();
4748

‎src/NHibernate.Test/VersionTest/Db/User.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ public class User
1111

1212
public virtual string Username { get; set; }
1313

14+
public virtual string NoOptimisticLock { get; set; }
15+
1416
public virtual ISet<Group> Groups { get; set; }
1517

1618
public virtual ISet<Permission> Permissions { get; set; }
1719
}
18-
}
20+
}

‎src/NHibernate.Test/VersionTest/Db/User.hbm.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8" ?>
1+
<?xml version="1.0" encoding="utf-8" ?>
22
<!--
33
Demonstrates how to control the optimistic locking behavior
44
of a collection (do changes to the collection result in
@@ -14,6 +14,7 @@
1414
</id>
1515
<timestamp name="Timestamp" column="ts" source="db"/>
1616
<property name="Username" column="user_name" type="string" unique="true"/>
17+
<property name="NoOptimisticLock" column="no_optimistic_lock" type="string" optimistic-lock="false"/>
1718
<set name="Groups" table="db_vers_user_group" batch-size="9" inverse="true" optimistic-lock="true" lazy="true" cascade="none" >
1819
<key column="user_id"/>
1920
<many-to-many column="group_id" class="Group" lazy="false" fetch="join" />
@@ -45,4 +46,4 @@
4546
<property name="Context" column="ctx" type="string"/>
4647
<property name="Access" column="priv" type="string"/>
4748
</class>
48-
</hibernate-mapping>
49+
</hibernate-mapping>

‎src/NHibernate/Async/Event/Default/DefaultFlushEntityEventListener.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -336,33 +336,35 @@ private async Task<object> GetNextVersionAsync(FlushEntityEvent @event, Cancella
336336
/// to synchronize its state to the database. Modifies the event by side-effect!
337337
/// Note: this method is quite slow, avoid calling if possible!
338338
/// </summary>
339-
protected Task<bool> IsUpdateNecessaryAsync(FlushEntityEvent @event, CancellationToken cancellationToken)
339+
protected asyncTask<bool> IsUpdateNecessaryAsync(FlushEntityEvent @event, CancellationToken cancellationToken)
340340
{
341-
if (cancellationToken.IsCancellationRequested)
342-
{
343-
return Task.FromCanceled<bool>(cancellationToken);
344-
}
341+
cancellationToken.ThrowIfCancellationRequested();
345342
IEntityPersister persister = @event.EntityEntry.Persister;
346343
Status status = @event.EntityEntry.Status;
347344

348345
if (!@event.DirtyCheckPossible)
349346
{
350-
return Task.FromResult<bool>(true);
347+
return true;
351348
}
352349
else
353350
{
351+
// call to HasDirtyCollections must not be optimized away because of its side effect
352+
bool hasDirtyCollections = await (HasDirtyCollectionsAsync(@event, persister, status, cancellationToken)).ConfigureAwait(false);
353+
354354
int[] dirtyProperties = @event.DirtyProperties;
355-
if (dirtyProperties != null && dirtyProperties.Length != 0)
356-
{
357-
return Task.FromResult<bool>(true); //TODO: suck into event class
358-
}
359-
else
360-
{
361-
return HasDirtyCollectionsAsync(@event, persister, status, cancellationToken);
362-
}
355+
return dirtyProperties != null && dirtyProperties.Length != 0 || hasDirtyCollections;
363356
}
364357
}
365358

359+
/// <summary>
360+
/// Check if there are any dirty collections.
361+
/// Has a side effect of setting the HasDirtyCollection property of the event.
362+
/// </summary>
363+
/// <param name="event"></param>
364+
/// <param name="persister"></param>
365+
/// <param name="status"></param>
366+
/// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
367+
/// <returns></returns>
366368
private async Task<bool> HasDirtyCollectionsAsync(FlushEntityEvent @event, IEntityPersister persister, Status status, CancellationToken cancellationToken)
367369
{
368370
cancellationToken.ThrowIfCancellationRequested();

‎src/NHibernate/Event/Default/DefaultFlushEntityEventListener.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -389,18 +389,22 @@ protected bool IsUpdateNecessary(FlushEntityEvent @event)
389389
}
390390
else
391391
{
392+
// call to HasDirtyCollections must not be optimized away because of its side effect
393+
bool hasDirtyCollections = HasDirtyCollections(@event, persister, status);
394+
392395
int[] dirtyProperties = @event.DirtyProperties;
393-
if (dirtyProperties != null && dirtyProperties.Length != 0)
394-
{
395-
return true; //TODO: suck into event class
396-
}
397-
else
398-
{
399-
return HasDirtyCollections(@event, persister, status);
400-
}
396+
return dirtyProperties != null && dirtyProperties.Length != 0 || hasDirtyCollections;
401397
}
402398
}
403399

400+
/// <summary>
401+
/// Check if there are any dirty collections.
402+
/// Has a side effect of setting the HasDirtyCollection property of the event.
403+
/// </summary>
404+
/// <param name="event"></param>
405+
/// <param name="persister"></param>
406+
/// <param name="status"></param>
407+
/// <returns></returns>
404408
private bool HasDirtyCollections(FlushEntityEvent @event, IEntityPersister persister, Status status)
405409
{
406410
if (IsCollectionDirtyCheckNecessary(persister, status))

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /