NHibernate Pitfalls: Merge
This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.
Sometimes there may be the need to store a loaded entity in a place that outlives the session that retrieved it.
Later on, you need to associate this entity with a new session, in order to continue using it; for this, you tipically use the Merge method. When you do this, however, you must use a new reference to the entity returned by this method:
1: Order order = HttpContext.Current.Session["order"] as Order;
2:
3: Order savedOrder = session.Merge<Order>(order);
4:
5: savedOrder.Customer = session.Load<Customer>(Int32.Parse(this.customerDropDownList.SelectedValue));
All future changes, such as setting property values, must be made to the merged entity, not the saved one, because NHibernate knows nothing about it:
1: Boolean contains = session.Contains(order); //false
2: Boolean containsSavedOrder = session.Contains(savedOrder); //true
Now you just have to Flush your session (or, better yet, commit your transaction) and the entity will be updated in the DB. Beware, though: if you don't set ALL of your entities' properties, the record in the database will be overwritten with the current values in this instance!