-->
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: Help with cascades (specifically cascade="save-update&q
PostPosted: Tue Feb 28, 2006 3:03 pm 
Newbie

Joined: Mon Nov 07, 2005 10:09 pm
Posts: 9
Location: Milwaukee
Hey guys,

I'm trying to understand cascades a little bit, and I seem to have run into a snag of sorts. I'm using NHibernate 1.0.0.

This is a sample hbm file for what I'm trying to do:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="BiaCreations.Core.Planet, BiaCreations.Core" table="Planets">

<cache usage="read-write" />

<id name="Id" column="PlanetId" type="Int32" unsaved-value="-1">
<generator class="native">
<param name="sequence">pm_planet_planetid_seq</param>
</generator>
</id>
<property name="Name" column="Name" type="string" length="64" />

<bag name="People" inverse="true" cascade="delete" lazy="true">
<cache usage="read-write" />
<key column="PlanetId" />
<one-to-many class="BiaCreations.Core.Person, BiaCreations.Core" />
</bag>
</class>

<class name="BiaCreations.Core.Person, BiaCreations.Core" table="People">

<cache usage="read-write" />

<id name="Id" column="PersonId" type="Int32" unsaved-value="-1">
<generator class="native">
<param name="sequence">pm_person_personid_seq</param>
</generator>
</id>
<property name="Name" column="Name" type="string" length="64" />

<many-to-one cascade="save-update"
name="Planet"
class="BiaCreations.Core.Planet, BiaCreations.Core"
column="PlanetId"
not-null="true"
/>

<bag name="Items" inverse="true" cascade="delete" lazy="true">
<cache usage="read-write" />
<key column="PersonId" />
<one-to-many class="BiaCreations.Core.Item, BiaCreations.Core" />
</bag>
</class>

<class name="BiaCreations.Core.Item, BiaCreations.Core" table="Items">

<cache usage="read-write" />

<id name="Id" column="ItemId" type="Int32" unsaved-value="-1">
<generator class="native">
<param name="sequence">pm_item_itemid_seq</param>
</generator>
</id>
<property name="Name" column="Name" type="string" length="64" />

<many-to-one cascade="save-update"
name="Person"
class="BiaCreations.Core.Person, BiaCreations.Core"
column="PersonId"
not-null="true"
/>
</class>
</hibernate-mapping>

__________________

Now in code, say I have a Planet object that has a couple Person objects in it's People collection. If I create a new Item, I would think that both the Person object and Planet object would be updated because of the cascade options that I specified.

That doesn't seem to be the case, though. I'm seeing the Person object being updated, but the Planet object doesn't seem to be. It contains an old version of the Person object in the People collection.

Am I doing something wrong or is this a limitation with cascading?

If you need more info, please let me know.

Thanks

Jim

_________________
Jim Geurts
CEO/Founder, Bia Creations
http://biacreations.com
Office: 414.213.1903
Fax: 414.294.3702


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 28, 2006 3:53 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
I think a code example would help here because it's a bit hard to understand what you are doing and what results you are expecting to get from a plain text description.

In particular, what is "an old version of the Person object" that Planet contains? Old compared to what? And why do you expect objects to change somehow just because you created another object?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 28, 2006 4:17 pm 
Newbie

Joined: Mon Nov 07, 2005 10:09 pm
Posts: 9
Location: Milwaukee
I was hoping that because I had cascade="save-update" specified on the one-to-many relationships, when that object was updated, it's related object's would be updated also. Maybe I'm asking too much, though :)

I know that there are better ways of doing what I'm outlining below, but it should provide an example of how I'm using the objects.

ISession session = SessionFactory.Instance.NHibernateFactory.OpenSession();

Planet planet = session.Load(typeof(Planet), 1) as Planet;

Person person = planet.People[0] as Person;

Item item = new Item();
item.Person = person;
item.Name = "Sample";

ITransaction trn = session.BeginTransaction();
try
{
session.Save(item);
trn.Commit();
}
catch (Exception)
{
trn.Rollback();
throw;
}

planet = session.Load(typeof(Planet), 1) as Planet;

// At this point, the person object has the correct Items count, but the
// collection on the planet object has not been updated with the new copy
// of the person object.

int itemCount = 0;
foreach (Person p in planet.People)
{
itemCount += p.Items.Count;
}


session.Close();
session.Dispose();

_________________
Jim Geurts
CEO/Founder, Bia Creations
http://biacreations.com
Office: 414.213.1903
Fax: 414.294.3702


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 01, 2006 5:55 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Doing work in two sessions in parallel in this way isn't really a good idea. You should remember that a session assumes it's running within one (logical) transaction and thus caches the objects associated with it, so your second Load call returns exactly the same object as the first one and doesn't go to the database at all, this may be the reason why it's unaware of changes.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 01, 2006 11:33 am 
Newbie

Joined: Mon Nov 07, 2005 10:09 pm
Posts: 9
Location: Milwaukee
Hrm... ok. I guess I just figured that the cascade for save-update would continue up along the object model like the cascade for delete does for bags. Thanks for your help.
[/code]

_________________
Jim Geurts
CEO/Founder, Bia Creations
http://biacreations.com
Office: 414.213.1903
Fax: 414.294.3702


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 02, 2006 3:02 am 
Newbie

Joined: Mon Nov 07, 2005 10:09 pm
Posts: 9
Location: Milwaukee
Out of curiosity, is there a way that I can trick nHibernate into thinking that the collection (on the planet object) hasn't been returned from the db (isn't cached)? Like if I set the collection property to null or something similar...

_________________
Jim Geurts
CEO/Founder, Bia Creations
http://biacreations.com
Office: 414.213.1903
Fax: 414.294.3702


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.