-->
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: One-to-many question
PostPosted: Mon Sep 29, 2008 1:20 pm 
Newbie

Joined: Sun Sep 28, 2008 2:49 pm
Posts: 6
Let's say I have a one-to-many relationship between Users and Addresses that I would like to map where each User may have multiple Addresses. From what I can tell, there are two ways to implement this relationship using NHibernate:

1. Bidirectional - each User object is aware of all the Addresses it has and each Address object is aware of the User object it belongs to.
2. Unidirectional - each User object is aware of all the Addresses it has, but each Address object is ignorant of which User it belongs to.

The bidirectional case is handled in the NHibernate documentation and seems to work just fine, but I can't seem to find much on how to implement the unidirectional one-to-many mapping.

A couple of questions I have with the unidirectional one-to-many mapping for the User/Address example:

1. Does the "UserID" column in the "Addresses" table have to be nullable in order to support this? It seems that NHibernate is performing a save before an update to this table when saving off a User, which ends up saving a null into the UserID column before updating it.
2. If the "UserID" column of the "Addresses" table has to be nullable, does that mean I also have to remove all foreign key constraints?
3. Do each of the Address objects have to store a UserID in order for this relationship to work? I assume so, otherwise if I were to call Save on an Address object, it wouldn't know what to write to the UserID column.
[/list][/list]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 29, 2008 2:36 pm 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
Quote:
1. Does the "UserID" column in the "Addresses" table have to be nullable in order to support this? It seems that NHibernate is performing a save before an update to this table when saving off a User, which ends up saving a null into the UserID column before updating it.


Yes.

Quote:
2. If the "UserID" column of the "Addresses" table has to be nullable, does that mean I also have to remove all foreign key constraints?


Yes.

Quote:
3. Do each of the Address objects have to store a UserID in order for this relationship to work? I assume so, otherwise if I were to call Save on an Address object, it wouldn't know what to write to the UserID column.


The UserId is written when the association is saved. In your scenario the User is the owner, so the association is saved with the User. If you just save the Address, you do not get the UserId filled up, which is correct since the Address doesn't know about the User. But you can call Save on the User and add cascading="all" to the collection mapping.

_________________
--Wolfgang


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 29, 2008 2:38 pm 
Expert
Expert

Joined: Mon Nov 26, 2007 2:29 pm
Posts: 443
kpanghmc ,

Quote:
1. Bidirectional - each User object is aware of all the Addresses it has and each Address object is aware of the User object it belongs to.
2. Unidirectional - each User object is aware of all the Addresses it has, but each Address object is ignorant of which User it belongs to.


Your characterization of unidirectional and bidirectional is correct.


Quote:
1. Does the "UserID" column in the "Addresses" table have to be nullable in order to support this? It seems that NHibernate is performing a save before an update to this table when saving off a User, which ends up saving a null into the UserID column before updating it.


That depends on your business model, specifically, if addresses can exist as as independent entities, not related to any particular User.
If they cannot, you can set the FK to not-null, and Hibernate will have to insert in one step.

Notice that this has nothing to do with the relationship being unidirectional or bidirectional.

I also remind you also, that NULL is, in SQL terms, a valid value for FK fields.


Quote:
3. Do each of the Address objects have to store a UserID in order for this relationship to work? I assume so, otherwise if I were to call Save on an Address object, it wouldn't know what to write to the UserID column.

The child object does not have a "userId" property.
If the relationship is unidirectional, it has nothing.
If the relationship is bidirectional, it holds a reference to the whole parent (a User object), not just its id.

_________________
Gonzalo Díaz


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 29, 2008 2:43 pm 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
Quote:
I also remind you also, that NULL is, in SQL terms, a valid value for FK fields.


Sorry, wasn't thinking. Gonzalo is right here.

_________________
--Wolfgang


Top
 Profile  
 
 Post subject: Thanks
PostPosted: Mon Sep 29, 2008 3:39 pm 
Newbie

Joined: Sun Sep 28, 2008 2:49 pm
Posts: 6
Thanks for the prompt replies.

So, if I understand you both correctly, I can define the Address class without a User or UserID property? What happens if I load a User object from NHibernate, make a change to one of its Addresses, and call Save on the Address instead of the User? Since the Address class doesn't have a User or UserID property, will NHibernate wipe out the UserID column for that particular Address or will it leave it alone?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 29, 2008 3:53 pm 
Expert
Expert

Joined: Mon Nov 26, 2007 2:29 pm
Posts: 443
kpanghmc,

I think what you are ultimately asking is this:

Do the mapping files, or the class diagram, look like my table DDL?
The answer is no.
Notice, for example, that the mapping file that Hibernate uses for a parent-child relationship creates the collection in the parent's mapping. In the DB, however, the most common representation of this an additional column in the child's table, and nothing in the parent's.


Create a short example with 2 classes, A and B, with a mapping file depicting a unidirectional parent-child relationship.
Don't create any tables, have Hibernate generate your tables from the mapping file.
Finally, experiment a little with some simple client code (create an A object, create a B object, add b to the children of a). Experiment with ant without not-null="true" in the foreign key.
Observe the generated SQL and the final state of the tables.

That will take you about 20 minutes (I can help you if you don't know how), and that will be worth 1000 responses here.

_________________
Gonzalo Díaz


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.