views:

99

answers:

2

Hi,

I have an object as follows

Public Class Bin

  Public Property Id As Integer

  Public Property Name As String

  Public Property Store As Store

End Class

Public Class Store

    Public Property Id As Integer

    Public Property Bins As IEnumerable(Of Bin)

End Class

I have a unique constraint in the database on Bin.Name and BinStoreID to ensure unique names within stores. However, when NHibernate persists the store, it first inserts the Bin records with a null StoreID before performing an update later to set the correct StoreID. This violates the Unique Key If I persist two stores with a Bin of the same name because The Name columns are the same and the StoreID is null for both.

Is there something I can add to the mapping to ensure that the correct StoreID is included in the INSERT rather than performing an update later? We are using HiLo identity generation so we are not relying on DB generated identity columns

EDIT: Mapping information for the store on the bin type is

<many-to-one class="NHS.EDC.SM.Data.Entities.Store, EDCBusinessLogic.SM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Store">
  <column name="StoreID" unique-key="UniqueBinKey" />
</many-to-one>

And for the bins on the store is

<set access="nosetter.camelcase-underscore" cascade="all-delete-orphan" inverse="true" name="Bins" mutable="true">
  <key>
    <column name="StoreID" />
  </key>
  <one-to-many class="NHS.EDC.SM.Data.Entities.Bin, EDCBusinessLogic.SM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</set>

Thanks

James

A: 

You must map the Bins collection as inverse and cascading, and always set both sides of the relationship (add to the collection, and set Bin.Store.

This is described in 6.4. One-To-Many Associations and 6.8. Bidirectional Associations

Diego Mijelshon
Thanks for the reply, I've added the mapping which I am using to the post but I think it's correct based on what you've said?
James
The mapping looks correct... I was going to ask if you were setting both sides, but then I saw your answer to Jamie Ide, so I believe you are.
Diego Mijelshon
A: 

Please show the code that is saving the Bin object. If you are doing it in this order:

session.Save(myBin);
bin.Store = myStore;
session.Flush();

NHibernate will generate an insert using the state of the object at the time Save was called and an update when Flush is called. Setting the Store property before flushing the session will correct this.

Jamie Ide
Yes, the object hierarchy is constructed first (with the appropriate backreferences) and then onyl the aggregate root (store) is saved
James