-->
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: What is the difference between cascade all and multi save()?
PostPosted: Sat Jun 03, 2006 12:05 am 
Regular
Regular

Joined: Tue Sep 02, 2003 5:09 pm
Posts: 81
Location: Whitefish Montana
I can't find anything that explains why a class mapped like this:

<class name="Owner" table="Owner">
<id name="OwnerId" column="OwnerId" type="Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid.comb"/>
</id>
<many-to-one name="Contact" column="ContactId" class="Contact" cascade="all"/>
</class>

<class name="Contact" table="Contact">
<id name="ContactId" column="ContactId" type="Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid.comb"/>
</id>
<property column="AddressLine1" type="String" name="AddressLine1" not-null="false" />
...
</class>

with just

session.save(owner)

works fine but removing the cascade="all" from the many-to-one with

session.save(contact)
session.save(owner)

results in a transient save error.

It seems like they should behave the same but I obviously don't understand something fundamental. Can anyone point me to a FAQ entry or documentation that will help me understand?

Thanks,

David


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 03, 2006 12:17 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
we are probably missing a property in the Contact class that relates back to Owner, no? if so, then you are trying to save a Contact that has a transient Owner resulting in an INSERT statement that contains an invalid value for OwnerID. More of your mapping file would help.

Again, just guessing but I'm thinking that you are having a problem with bi-directional associations and if so, this is the doco:

http://www.hibernate.org/hib_docs/nhibe ... irectional

although, the Hibernate in Action book has more info...

Post more of your mapping file for Contact class and the error log describing the save error and I'll see if I'm on the right track...

-devon


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 03, 2006 12:49 am 
Regular
Regular

Joined: Tue Sep 02, 2003 5:09 pm
Posts: 81
Location: Whitefish Montana
Thanks for the quick reply. I have tried with and without the following:

<bag name="Owner" access="nosetter.camelcase" inverse="true" lazy="true" >
<key column="ContactId" />
<one-to-many class="Owner" />
</bag>

Including it did not seem to make a difference. When that was included In the contact class I had an IList getter for Owner. I have also tried

session.save(owner)
session.save(contact)

as well as

session.save(contact)
session.save(owner)

The only thing I cut out of the contact class mapping were further address fields like city, state and zip.

I am just developing some unit tests to make sure I have the basics working before I get too far into a new project. I haven't used NHibernate and it has been a couple of years since I used Hibernate.

Thanks,

David


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 03, 2006 1:34 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
i think i'm really missing something in how your associations are supposed to work. I _think_ you have:

Owner many-to-one Contact

and the inverse

Contact one-to-many Owner

if that is true, then you have to have the association mapped:

Code:
<class name="Owner">
    <many-to-one name="Contact">
</class

<class name="Contact">
    <bag name="Owners" lazy="true" inverse="true">
        <key column="ContactID" />
        <one-to-many class="Owner" />
    </bag>
</class>


this particular mapping would require you to do something like:

Code:
Owner o = new Owner();
session.Save(o);

...

Contact c = new Contact();
c.Owners.Add(o);
o.Contact = c;

session.Save(c);
session.Update(o);


but that isn't really very clean. I personally would implement cascade on the Contact class:

Code:
<class name="Contact">
    <bag name="Owners" lazy="true" inverse="true" cascade="save-update">
        <key column="ContactID" />
        <one-to-many class="Owner" />
    </bag>
</class>


this would allow you to:

Code:
Owner o = new Owner();
Contact c = new Contact();

c.Owners.Add(o);
o.Contact = c;

session.Save(c);


because the collection is configured to cascade the save and update calls, NH will automagically save the owner first, get the guid, then save the contact with the correct reference to the owner...

am i helping? like i said, i think i'm missing something in your associations...

-devon


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 03, 2006 1:57 am 
Regular
Regular

Joined: Tue Sep 02, 2003 5:09 pm
Posts: 81
Location: Whitefish Montana
Thank you, your replay has been useful. I am trying to find out the best way to model and map certain types of relationships. It works fine with cascade="all" but that isn't what I want to do. I don't understand how that is different than multiple saves without cascade="none". I would rather save each instance myself since not all contacts are owners.

My class model is not what I really want because I haven't seen a good way to map an interface of IContactable. Since I have owners, buyers, agents, etc. that would be better off implementing something like IContactable. It really doesn't make sense to tie updates to Owners (or the other classes that would implement IContactable). From the link you posted, it looks like I should consider a joined-subclass.

Thanks,

David


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 03, 2006 2:34 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
well i don't really understand the complexities of your business model, but, i'm guessing you are implementing a real estate app of some sort. i might model things with a Person object that 1-1 ContactInformation object. then for each Asset, there is a buyer, seller, and agent all mapped to a person object, each of which have thier contact info...

Certainly we know in the real world that Agents are often times both Buyers and Sellers. Buyers are often Sellers and Sellers are often Buyers. And as a business we'd like to think that a Seller will become a Buyer keeping that revenue stream flowing. Since an object cannot change its type, it would be better to implement the relationships for this type of situation and allow then Person to play many "roles" in the system. of course that's only my opinion. like i said, i don't have any knowledge of your problem domain.

-devon


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.