Consider the following mapping:

Mapping of Map and GroupLayer
<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 index column. It is a good convention to use the same prefix as used for the key column. The mapping of grouplayer then looks like this:

Mapping of GroupLayer
<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>
  • No labels