kubut
kubut

Reputation: 315

NHibernate: insert object to collection

I have 2 classes in my NHibernate project: OrderModel and OrderProductModel:

public class OrderModel
    {
        public OrderModel() { productList = new HashedSet<OrderProductModel>();}
        (...)
        public virtual ISet<OrderProductModel> productList { get; set; }
    }


public class OrderProductModel
    {
        (...)
        public virtual OrderModel orderM { get; set; }
    }

I mapping it this way:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Shop.Domain.Model.Order" assembly="Shop.Domain">
  <class name="OrderModel">
    <id name="id" column="id">
      <generator class="native" />
    </id>
    <set name="productList" lazy="false" inverse="true" cascade="save-update" table="OrderProductModel" >
      <key column="orderM"/>
      <one-to-many class="OrderProductModel"/>
    </set>
    (...)
  </class>
</hibernate-mapping>


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Shop.Domain.Model.Order" assembly="Shop.Domain">
  <class name="OrderProductModel">
    <many-to-one name="orderM" class="OrderModel" column="orderM"/>
    (...)
  </class>
</hibernate-mapping>

Now I want to insert order to database by something like this:

var p1= new OrderProductModel{...};
var p2= new OrderProductModel{...};
var order = new OrderModel{...};
p1.orderM = order;
p2.orderM = order;
order.productList = new HashedSet<OrderProductModel>{p1, p2} // from Iesi
session.Insert(order) // session is IStatelessSession and it must be

It insert order to datebase, but table OrderProductModel is still empty. I realy don't want insert orderProduct manually, I expect NHibernate can to this for me, but I have no idea how.

Upvotes: 1

Views: 1491

Answers (1)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123861

You are almost there. Because we used inverse="true" we must set both sides of relation

var p1= new OrderProductModel{...};
var p2= new OrderProductModel{...};
var order = new OrderModel{...};

// new lines
// these are essential part to make inverse mapping to happen
p1.orderM = order;
p2.orderM = order;

order.productList = new HashedSet<OrderProductModel>{p1, p2} // from Iesi

What is all about? Why to do that?

Because with setting inverse="true" we say: NHibernate - when you handle collection items - let it on these items. They will take care about save/udpate. So they must know about relationship

That all will work with standard session if we will call

session.Save(order);
session.Flush();

In case, that we would like to use stateless session, we should know:

13.2. The StatelessSession interface

Alternatively, NHibernate provides a command-oriented API that may be used for streaming data to and from the database in the form of detached objects. A IStatelessSession has no persistence context associated with it and does not provide many of the higher-level life cycle semantics. In particular, a stateless session does not implement a first-level cache nor interact with any second-level or query cache. It does not implement transactional write-behind or automatic dirty checking. Operations performed using a stateless session do not ever cascade to associated instances.

So there is no way to profit from the fact that we do have cascading in place

The way to go is:

session.Save(order);
session.Save(p1);
session.Save(p2);

Upvotes: 1

Related Questions