Consider the following mapping:
<class name="SharpMap.Layers.GroupLayer, SharpMap" table="grouplayer"> <list name="Layers" lazy="false" cascade="all" collection- type="DeltaShell.Plugins.Data.NHibernate.Collections.Generic.PersistentEventedListType`1[[SharpMap.Layers.ILayer, SharpMap]], DeltaShell.Plugins.Data.NHibernate"> <key column="parent_layer_id"/> <index column="list_index" /> <one-to-many class="SharpMap.Layers.ILayer, SharpMap"/> </list> </class> <class name="Map" table="map" lazy="false" > <id name="Id" column="id" type="Int64"> <generator class="native" /> </id> <list name="Layers" lazy="false" cascade="all-delete-orphan" collection-type="DeltaShell.Plugins.Data.NHibernate.Collections.Generic.PersistentEventedListType`1[[SharpMap.Layers.ILayer, SharpMap]], DeltaShell.Plugins.Data.NHibernate"> <key column="map_id"/> <index column="list_index" /> <one-to-many class="SharpMap.Layers.ILayer, SharpMap"/> </list> </class>
As you can see both grouplayer and Map have a list of layers (ILayer) when are mapped in a <list> element. This will result in a 'schema' like this:
Since a layer is in not the collection of map layers and in a grouplayer at the same time the list_index could be shared right??? Unfortunately this is not the case. Consider the following:
1 Add a map
2 Add a grouplayer to the map
3 To that grouplayer add another layer
4 Save / Load
5 Now move the layer of 3 out of the grouplayer into the map of 1.
6 Save / Load
7 An expcetion will occur: something like 'null index column for collection: SharpMap.Map.Layers'
Now what is happening? During the save of 6 we see the following sql (with NHibernate Profiler)
UPDATE layer SET parent_layer_id = null, list_index = null WHERE parent_layer_id = 2 /* @p0 */ AND id = 6 /* @p1 */
This is were NHibernate is removing the layer out of the grouplayer. NHibernate sets the list_index to null and therefore messes up Maps->Layers relationship. As NHibernate considers the relationships unrelated this is should be valid.
So....for every relationship use a separate list_index column. It is a good convention to use the same prefix a for the key column the mapping might look like this:
<class name="SharpMap.Layers.GroupLayer, SharpMap" table="grouplayer"> <list name="Layers" lazy="false" cascade="all" collection- type="DeltaShell.Plugins.Data.NHibernate.Collections.Generic.PersistentEventedListType`1[[SharpMap.Layers.ILayer, SharpMap]], DeltaShell.Plugins.Data.NHibernate"> <key column="parent_layer_id"/> <index column="parent_layer_list_index" /> <one-to-many class="SharpMap.Layers.ILayer, SharpMap"/> </list> </class>