Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Unidirectional one to many association on a FK
PostPosted: Sat Apr 01, 2006 1:03 am 
Newbie

Joined: Thu Aug 25, 2005 5:33 pm
Posts: 10
Hi,

the documentation says that a Unidirectional one to many association on a FK is a very unusual case, and not really recommended. Instead the documentation recommends doing a unidirectional 1-to-M using a join table.

I've looked in the forums and documentaiton, but cant find the reason why the join table approach is recommended? Can anybody explain this or point to a reference that does?

thanks,

row


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 03, 2006 12:36 am 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
If you use a foreign key for this, it becomes unique: after all, one set of many-end objects can't belong to multiple one-end objects, that's what many-to-many is for. So if you do use a foreign key, you've now got two columns that both uniquely describe the one-end object, and that's just a waste of space, redundant information, and a potential source of bugs (if, for example, you were to accidentally leave out the unique attribute on the DB column). So doing this is discouraged.

This is also why the one-to-one used to be primary-key only. I think that the hibernate team should have stuck to their guns on this one, and not allowed property-ref on one-to-one mappings. But that's just me..


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 7:27 pm 
Pro
Pro

Joined: Tue Aug 26, 2003 8:07 pm
Posts: 229
Location: Brisbane, Australia
tenwit wrote:
If you use a foreign key for this, it becomes unique: after all, one set of many-end objects can't belong to multiple one-end objects, that's what many-to-many is for. So if you do use a foreign key, you've now got two columns that both uniquely describe the one-end object, and that's just a waste of space, redundant information, and a potential source of bugs (if, for example, you were to accidentally leave out the unique attribute on the DB column). So doing this is discouraged.


Hey, sorry to necro-post - but could anyone possibly explain this explanation for me?

I would like to understand the issues behind this statement. I often have trouble justifying my schemas to various DBAs with the explanation "the hibernate team recommends...".

We have a large number of one-to-many associations in our model and the DBAs / report writers are already moaning about surrogate keys(*). Adding a whole bunch of many-to-many link tables to map one-to-many relationships (each of which will have nothing but surrogate keys on them) is going to... cost me some DBA karma.

Are there any features of Hibernate that we will not be able to use, or that will be harder to use if we map with a simple FK relation? (**)



(*) Not really, I'm good at explaining surrogate keys these days; but we *did* have to argue for a while.

(**) We are aware of the fact that using unidirectional associations in the model will make querying harder. My question is about the statement in the documentation relating to how you map that association (FK versus link table).

_________________
Cheers,
Shorn.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 11:57 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
My excessive wordiness confuses me sometimes. It doesn't help that's it's 5pm on Friday and I'm starting my second beer. I probably did have a good point, but I can't see it now.

Anyway, consider this, much simpler argument: a unidirectional one-to-many requires a column in the many-table that is not used in the mapping of that class. It is used only by the mapping of the one-table class. It's not particularly intuitive, and it begs the question: why is the column in the many-table? It's obviously not part of the object, otherwise it would be in the mapping.

Therefore, the official suggestion is to use a link table. This removes the child-to-parent relationship from the child table, which is good because (according to your chosen mapping), the child doesn't have a relationship with the parent: the only relationship is parent-to-child. The new link table is conceptually part of the parent, and the child (and its mapping) know nothing about it. No loss of information and more cohesive schema/mapping integrity.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 24, 2006 12:42 am 
Pro
Pro

Joined: Tue Aug 26, 2003 8:07 pm
Posts: 229
Location: Brisbane, Australia
Okay,

That is a much clearer reason (and one which I don't disagree with).

OTOH, it's pretty touchy-feely. Beyond having a physical schema that is (arguably) more elegant and (definitively) more consistent with the intent of the domain model - are there any other reasons you can think of?

In the end, it's not my schema - the DBA group owns the schema and has to sign off on it (especially as relates to the schema's "reportability"). I am inclined to give the DBAs the structure they want on this one if it doesn't affect the functionality hibernate can give me.

Thanks for the prompt reply.
Especially since it's cutting into beer o'clock-time. ;)

_________________
Cheers,
Shorn.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 26, 2006 5:11 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
No, the only reasons I can think of (even now, on Monday morning) are the potential for DB-level bugs due to neglecting to enforce uniqueness (which you can ignore if you have a whole DBA department), and the increased mapping-to-schema cohesiveness. You don't lose anything by doing it the non-recommended way.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject: Re: Unidirectional one to many association on a FK
PostPosted: Mon Dec 11, 2006 12:59 pm 
Newbie

Joined: Mon Nov 27, 2006 2:11 pm
Posts: 6
From a design point of view the reason is that a one to many mapping with no join table populates the many side table with columns that don't belong to that entity, are there only for "linking" porpuses. You can find this argument a little purist, after all one extra column is not that chaos, but take into account that when a system scales your tables have the tendency of being related with a lot more, so it's not an unusual case that one table have multiple columns that are there with the only purpose of linking.

From a working group point of view if you have a lot of developers that have to interact with the same set of tables it's better they don't have to deal with data they are not interested in, so only the ones interested in the relation take into account the join tables.

In summary, this strategy decouples your database in two sets: your "clean" entity tables (the relation is not part of the object) and joining tables, and nobody has to deal/understand extra data if he/she is not interested in.

There is an exception to this pattern: if your many side table represents a weak entity, i.e. one that doesn't make sence to exist by its own and all its records have to be related to its parent table. In those cases the weak table will probably not be related to other table but its unique parent one, so you can arguee that the extra join column is part of the entity (after all the entity has no sence if it's not related to its unique parent) and then avoid the join one.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 12, 2006 2:06 am 
Newbie

Joined: Thu Jun 09, 2005 7:12 am
Posts: 7
tenwit wrote:
Snip

So if you do use a foreign key, you've now got two columns that both uniquely describe the one-end object, and that's just a waste of space, redundant information, and a potential source of bugs (if, for example, you were to accidentally leave out the unique attribute on the DB column). So doing this is discouraged.



I'm a little confused about the unique attribute on the DB

Consider the following case...

PARENT_TABLE
==========
PARENT_ID PK


CHILD_TB
=======
CHILD_ID PK
CHILD_NAME
PARENT_ID FK (To the parent table- Neither nullable nor unique. This would imply a child with no parent(orphan) if parent_id is null and many children can have the same parent id avoiding the unique)


Unless I'm missing something really simple... Why does there need to be a unique attribute on the foreign key ??

As for the Join table recommendation, I think the value add from a datamodel point of view will also come from the view of scalability in the sense that if some relationships change from one-many to many-many, having a join table would help to achieve it easier (by simply removing the constraint for uniqueness in the combination

eg.

JOIN_TABLE
========
PARENT_ID
CHILD_ID - Unique key (to ensure one to many)


Now just drop the unique key to make it many to many


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 12, 2006 4:08 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
devu wrote:
Why does there need to be a unique attribute on the foreign key ??

I was talking about a foreign key column on the parent table, which isn't what your diagram shows.

PARENT_TABLE
==========
PARENT_ID PK
PARENT_REF <- Column that would need uniqueness constraint.


CHILD_TB
=======
CHILD_ID PK
CHILD_NAME
PARENT_REF FK

The column that you are talking about obviously needs to not have a uniqueness constraint, as that would be a one-to-one on a FK.

I'm not sure that the original question was actually asking the question that I answered. I'm certain that neither you nor stolley were referring to that (rather strange) arrangement of having a separate PK and FK-reference-column in the parent table, and I think that that's where your confusion arises.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 13, 2006 7:29 pm 
Pro
Pro

Joined: Tue Aug 26, 2003 8:07 pm
Posts: 229
Location: Brisbane, Australia
The structure I am talking about is like the following:

PARENT_TABLE
==========
PARENT_ID PK


CHILD_TB
=======
CHILD_ID PK
CHILD_NAME
PARENT_ID FK


Where the FK on the child refers to the PK of the parent, which obviously is guaranteed to be unique.

_________________
Cheers,
Shorn.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 13, 2006 8:11 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
THat's the normal situation, so it doesn't need any additional constraints. The arguments for using a link table are as described by leomena above. From a purely relational point of view, your design is fine.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject: Another reason I can think of...
PostPosted: Thu Mar 08, 2007 2:46 pm 
Newbie

Joined: Thu Mar 08, 2007 2:31 pm
Posts: 2
I think another reason Hibernate recommends the use of a join table is that the schema update feature. I think you can easiy change the unidirectional to bidirectional if you use a join table. However, if you are joining tens of entity tables and each join needs a join table, it will degrade the speed (in general). I still don't get why hibernate STRONGLY recommand the use of a join table though...


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 18, 2007 11:03 pm 
Newbie

Joined: Sun Mar 18, 2007 10:56 pm
Posts: 3
Location: San Diego, CA
I have read this entire thread and I just want to make sure I understand this correctly: NHibernate not only strongly recommends you use a linking table for One to many relationships but it does not even support One to many relationships using a foriegn key?

As someone who is trying to transition from another ORM, this just seems crazy. After reading the rational above, it seems that it is an attempt to keep the DB model "clean" by not cluttering up child tables with foreign keys. To me this just seems like a bad case of allowing your object model dictate what your data model will look like and vice versa. Isn't the point of ORM tools to map between the two, not to make them look the same?

Please let me know if I am not understanding this correctly and help me to see exactly how this situation (which I believe is EXTREMELY common in the DB world) is typically handled in NHibernate.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 18, 2007 11:16 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
There's one important fact that you've omitted. NHibernate (and Hibernate in general) does not support unidirectional one-to-many relationships on a foreign key.

If you want the objects to appear to be related unidirectionally, but the foreign key issue is a blocker for you, you can always make the relationship bidirectional and simply omit child.getParent() from the child's interface. It is required in the implementation and mapping, though.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 18, 2007 11:19 pm 
Newbie

Joined: Sun Mar 18, 2007 10:56 pm
Posts: 3
Location: San Diego, CA
tenwit wrote:
There's one important fact that you've omitted. NHibernate (and Hibernate in general) does not support unidirectional one-to-many relationships on a foreign key.

If you want the objects to appear to be related unidirectionally, but the foreign key issue is a blocker for you, you can always make the relationship bidirectional and simply omit child.getParent() from the child's interface. It is required in the implementation and mapping, though.


So does this mean that I would have to have a foreign key in both the child and the parent class?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next

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.