I checked the NH source code, it seems to only check the dirty collection when checking if version increment is needed, and the collection will only get dirty when adding/removing items, not the ones in the collection Any item is dirty.
I have the following mapping:
public class OrderMap: ClassMap
{
public OrderMap()
{
Id(c => c.Id).GeneratedBy.GuidComb();
Version(c => c.Version);
OptimisticLock.Version( );
HasMany(x => x.OrderLines)
.Inverse()
.Cascade.AllDeleteOrphan();
}
}
public class OrderLineMap: ClassMap
{
public OrderLineMap()
{
Id(x => x.Id).GeneratedBy.GuidComb();
Map(x => x.Quantity);
References(x => x.Order);
}
}
So my question is, this Is it the expected behavior? That is to say, only when the sub-collection is modified with remove/add, the version will be updated when the sub-entity is modified. It kind of breaks the aggregate root concurrency model.
Ayende’s more information in this article:
http://ayende.com/blog/4055/nhibernate -automatic-change-tracking-for-aggregate-roots-in-ddd-scenarios
If I read the documentation correctly, if I have one that uses the version column mapping Order entity (increased by nhibernate), then changes to the order line should update the version number of the aggregate root (order). It does do this when I add/remove order lines, but if I only change, for example, the quantity on the order line , The version of the order will not be updated. Is this expected behavior?
I checked the NH source code, it seems to only check the dirty collection when checking if version increment is needed, and the collection will only get dirty when adding/removing items, not the ones in the collection Any item is dirty.
I have the following mapping:
public class OrderMap: ClassMap
{
public OrderMap()
{
Id(c => c.Id).GeneratedBy.GuidComb();
Version(c => c.Version);
OptimisticLock.Version( );
HasMany(x => x.OrderLines)
.Inverse()
.Cascade.AllDeleteOrphan();
}
}
public class OrderLineMap: ClassMap
{
public OrderLineMap()
{
Id(x => x.Id).GeneratedBy.GuidComb();
Map(x => x.Quantity);
References(x => x.Order);
}
}
So my question is, this Is it the expected behavior? That is, only when you use remove/add to modify the sub-collection, the version will be updated when the sub-entity is modified. It kind of breaks the aggregate root concurrency model.
This is indeed the expected behavior. There is a way to solve it using an event listener that can detect changes in the child process and traverse to the aggregate root and lock it in an optimistic way (triggering version changes) .
Ayende’s more information in this article:
http://ayende.com/blog/4055/nhibernate-automatic-change-tracking-for-aggregate-roots -in-ddd-scenarios