Skip to content

Commit e4a0e0d

Browse files
committed
Incrementing Version on parent entity for a collection change works correctly even with optimistic-lock="false" on another property of the same entity. Call to HasDirtyCollections has a side effect thus must be called independently from the existence of other dirty properties.
1 parent 356ff7f commit e4a0e0d

File tree

4 files changed

+19
-11
lines changed

4 files changed

+19
-11
lines changed

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/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)