-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Working with Collections
PostPosted: Thu Sep 25, 2008 1:43 pm 
Beginner
Beginner

Joined: Tue Dec 04, 2007 4:48 pm
Posts: 21
Hi,

I kinda get the feeling I'm missing out on something ... I have to class (and two tables in my db), which have a one-to-many relation. So now I want to create a new order, and add that to the list of orders of an customer, so I tried this code:

Code:
Customer c = new Customer { Alter = 23, Name = "BigBoss" };
Order o = new Order {Amount=100, Date=new DateTime(2008, 8, 18)};

c.Orders.Add(o);

session.Save(c);
session.Flush();
session.Clear();

Customer fromDb = session.Get<Customer>(c.Id);

Assert.AreEqual(c.Name, fromDb.Name);
Assert.AreEqual(c.Orders.Count, fromDb.Orders.Count);


But my second assertion fails :( looking at the db-table I notice the customer-id is missing in the order.

I would assume, that nhibernate would take care of everything :(

and this are my mappings:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SqlEngines" namespace="SqlEngines">
  <class name="Customer">
    <id name="Id">
      <generator class="native"></generator>
    </id>
    <property name="Name"/>
    <property name="Alter" column="Age"/>
    <bag name="Orders" inverse="true" cascade="all">
      <key >
        <column name="CustomerId" not-null="true"/>
      </key>
      <one-to-many class="Order"/>
    </bag>
  </class>
  <class name="Order" table="CustomerOrder">
    <id name="Id">
      <generator class="native" />
    </id>
    <property name="Date" column="OrderDate"/>
    <property name="Amount"/>
    <many-to-one name="MyCustomer" class="Customer" column="CustomerId" not-null="true" />
  </class>
</hibernate-mapping>


BTW: I'm using .Net 3.5 and NHibernate 1.2.1.4000


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 25, 2008 4:06 pm 
Newbie

Joined: Mon May 05, 2008 10:34 am
Posts: 11
Location: Houston, TX
Try changing your save from:

Code:
session.Save(c);


To

Code:
session.Save(c);
session.Save(c.Orders[0]);


This has worked for me in the past.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 26, 2008 2:24 am 
Regular
Regular

Joined: Tue Jul 29, 2008 3:30 am
Posts: 74
You have mapped your Orders collection as inverse, so a save or update of c won't change anything for the orders in the collection.

If you want to save a order, you have to call session.Save() for it.

If you want to change the customer of an order, you have to change the MyCustomer property to the new customer, changes to the orders collection of a customer won't be saved.

c.Orders.Add(o) won't set the MyCustomer property of o. You have to do that yourself.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 26, 2008 4:21 am 
Beginner
Beginner

Joined: Tue Dec 04, 2007 4:48 pm
Posts: 21
kibbled_bits wrote:
Try changing your save from:

Code:
session.Save(c);


To

Code:
session.Save(c);
session.Save(c.Orders[0]);


This has worked for me in the past.


Well, I would not prefer to save my data this way, because I would like NH to take care of persisting the orders, instead of me, looping over all orders in my code ... that's a responsibility of the ORM (in my point of view).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 26, 2008 4:27 am 
Beginner
Beginner

Joined: Tue Dec 04, 2007 4:48 pm
Posts: 21
cremor wrote:
You have mapped your Orders collection as inverse, so a save or update of c won't change anything for the orders in the collection.


Why would that be? As far as I understand the inverse=true just declares that the order-entity is the owner of the relationship (as described in http://bchavez.bitarmory.com/archive/2007/10/06/nhibernate-and-inversetruefalse-attribute.aspx.

If you want to save a order, you have to call session.Save() for it.

cremor wrote:
If you want to change the customer of an order, you have to change the MyCustomer property to the new customer, changes to the orders collection of a customer won't be saved.

c.Orders.Add(o) won't set the MyCustomer property of o. You have to do that yourself.


OK, so I tried some settings (kinda at random) ... and I came up with these changes:

Code:
<many-to-one name="MyCustomer" column="CustomerId" class="Customer"  />

[...]

Customer c = new Customer { Alter = 23, Name = "BigBoss" };
Order o = new Order {Amount=100, Date=new DateTime(2008, 8, 18), MyCustomer = c};

c.Orders.Add(o);             

session.Save(c);


which results in the desired behavior. So I had to remove the not-null=true attribute from the many-to-one element and had to explicitly assign the customer to the newly created order.[/url]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 26, 2008 1:53 pm 
Regular
Regular

Joined: Tue Oct 16, 2007 9:45 am
Posts: 93
If you look in the documentation on bidirectional realtionships it explicitly says that they are not synchronized by NH. You have to do that yourself. You migh want to take a look at observable collections. Here is a link to one of my posts before
http://forum.hibernate.org/viewtopic.ph ... highlight=


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.