Question

I have a class called Shape that has a many to many relation with Package. The meaning of this bidirectional relation is that if a Product has a certain Shape, it can be Packaged by the Packages the Shape is associated with. The also applies to the inverse, if product is packaged by Package, this means that Product should be of a Shape associated with this Package.

Therefore, I have a domain model with Shape containing Packages and Package containing Shapes. The NH mapping is accordingly resulting in a Shape, Package and PackageToShape table.

However, when I apply versioning, this leads to multiple updates and inserts in the PackageToShape table. Actually, what happens is that a relation for example like: ShapeId = 1, PackageId = 1 is removed first and then inserted again! In reality I use Guids. But the point is that with this setup NH is creating multiple delete and insert statements on the many to many table first deleting a row then adding the exact same row again!!

Is there a way to prevent this from happening??

Mappings (using Fluent NH)

public sealed class ShapeMap: EntityMap<Shape, Guid, ShapeDto>
{
    public ShapeMap()
    {
        HasManyToMany(s => s.Packages)
            // Fetch.Join will raise laizy collection load error
            .Fetch.Select()
            .AsSet()
            .Cascade.All();
        HasManyToMany(s => s.UnitGroups)
            // Fetch.Join will raise laizy collection load error
            .Fetch.Select()
            .AsSet()
            .Cascade.All();
        HasManyToMany(s => s.Routes)
            // Fetch.Join will raise laizy collection load error
            .Fetch.Select()
            .AsSet()
            .Cascade.All();
    }

Mapping for Package:

public class PackageMap : EntityMap<Package, Guid, PackageDto>
{
    public PackageMap()
    {
        Map(p => p.Abbreviation).Not.Nullable().Length(30).Unique();
        HasManyToMany(p => p.Shapes)
            // Fetch.Join will raise laizy collection load error
            .Fetch.Select()
            .AsSet()
            .Inverse()
            .Cascade.All();
    }
}

Entity map implements Id, Name (unique) and Version mappings.

Was it helpful?

Solution

I found out the problem. In setters of collections I created new lists and apparently this you cannot do with NH. I wanted to expose my inner HashSets as IEnumerable to the outside world, which I think is the preferred way to do. In my protected setters of these collections I had code like:

protected set { _mySet = new HashSet(value); }

The second problem I ran into was that NH does not support native dot net 4 ISet. You have to implement the NH provided set (Iesi.Collections.Generic.ISet).

What happened was that because I created a new internal collection from the collection provided by NH, NH thought, Ok, this is not the same collection, so, this object is dirty, hence update the version and start cascading these changes.

This question I asked summarizes the dilemmas I was wrestling with but now seem solved: Approach to handle business collections

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top