tags:

views:

1389

answers:

1
+6  A: 

Can this have anything to do with the fact that you have a surrogate key in the storeproducts table ?

What happens if you remove this surrogate key column Id, and put the primary key on the combination of the product_id and store_id columns ?

I believe that, if you want to have a surrogate key on the storeproducts table, you'll have to create yet another entity.

If you want to use the surrogate key, you'll have to use the idbag mapping.

How does your Product class and mapping look like ? I see that you specify the 'inverse' attribute in your mapping of the Products collection in the Store entity.

If you do this (and thus you have a bi-directional association), then you should add the Store to the Stores collection of the product as well. Since -from the NH documentation- :

Changes made only to the inverse end of the association are not persisted. This means that NHibernate has two representations in memory for every bidirectional association, one link from A to B and another link from B to A. This is easier to understand if you think about the .NET object model and how we create a many-to-many relationship in C#:

category.Items.Add(item);          // The category now "knows" about the relationship
item.Categories.Add(category);     // The item now "knows" about the relationship

session.Update(item);                     // No effect, nothing will be saved!
session.Update(category);                 // The relationship will be saved

The non-inverse side is used to save the in-memory representation to the database. We would get an unneccessary INSERT/UPDATE and probably even a foreign key violation if both would trigger changes! The same is of course also true for bidirectional one-to-many associations.

You may map a bidirectional one-to-many association by mapping a one-to-many association to the same table column(s) as a many-to-one association and declaring the many-valued end inverse="true".

This means, that only one of the ends should be inverse. Adding a Product to a store, should be done like this:

public class Store
{
   public void AddProduct( Product p )
   {
       if( _products.Contains (p) == false )
       {
             _products.Add (p);
             p.AddStore(this);
       }
   }
}
public class Product
{
    public void AddStore( Store s )
    {
       if( _stores.Contains (s) == false )
       {
          _stores.Add (s);
          s.AddProduct(this);
       }
    }
}

(Very important to check whether the collection already contains the item to be added; otherwise you'll end up in an infinite loop.

Frederik Gheysels
I tried to change the db as you suggested. But no, still it doesn't work.
Ngu Soon Hui
Updated my post a bit; can you show the (relevant) code and mapping of the Product class ?
Frederik Gheysels
I have updated the question to include the Product class and its mapping
Ngu Soon Hui
Both ends are set to inverse ? You should have only one inverse end, and make the association at both ends (see my update)
Frederik Gheysels
Thanks, your solution works..
Ngu Soon Hui