I'm doing some tests using NHibernate and I currently have two mapped entities, Orders and Products. As always an Order has a collection of Products, and I'm mapping this as:
<bag name="Products" cascade="all" lazy="true">
<key column ="Order_ID" />
<many-to-many class="Product" column="Product_ID" />
</bag>
And on the C# side:
public virtual IList<Product> Products
{
get { return _Products; }
set { _Products = value; }
}
private IList<Product> _Products = new List<Product>();
In the case I have one persisted Order (John's order) in the database with some items in its Products collection (an apple, an orange and a coconut) and I try to add a new item to the collection (a banana) I can see from the SQL output that NHibernate is doing something like this:
INSERT INTO Products_Table (Product_Name, Product_ID) VALUES ('Banana', @Banana_ID)
DELETE FROM Products WHERE Order_ID = @Johns_Order_ID
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Apple_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Orange_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Coconut_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Banana_ID)
Instead of simply doing something like this:
INSERT INTO Products_Table (Product_Name, Product_ID) VALUES ('Banana', @Banana_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Banana_ID)
So why does NHibernate delete all associations from the Products table to recreate them again when I'm only trying to insert a new product in it? How to avoid it?
Thanks in advance!
PS: I tried to use the inverse mapping attribute as suggested in this SO Question but even though the new product gets saved its association with an order doesn't.
EDIT:
Here is the code I'm using to modify the products list:
Order order = session.Load<Order>(orderId);
order.Products.Add(new Product() { Name = "Banana" });
using (ITransaction transaction = session.BeginTransaction())
{
session.Update(order);
transaction.Commit();
}