-->
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.  [ 8 posts ] 
Author Message
 Post subject: Polymorphic Mapping Q - Single Child/Polymorphic Parents
PostPosted: Thu Apr 21, 2005 11:35 am 
Newbie

Joined: Thu Apr 21, 2005 11:11 am
Posts: 5
Location: Boston, MA
I've been using Hibernate for the past few months, and have bumped up against a mapping question that I haven't seen referenced in the forums or wiki. I've got a polymorphic parent object that has a child that I'd like to reuse among different parent types. An example:

Say I have a Content base class with two subclasses: Article and Discussion. I want to be able to attach a Comment object to any Content object. Article and Discussion are probably not in the same table (ideally we'd like to attach a Comment to anything that implements a Commentable interface), so Comment is going to need some sort of a discriminator to indicate the type of the parent class.

The only way I can think of mapping this scenario is mapping the discriminator in the comment table to subclasses of Comment that mirror the Content class hierarchy (i.e. have ArticleComment and DiscussionComment). Is there another option for mapping this problem? I ideally don't want to mirror the parent's hierarchy and create classes that only differ by their discriminators. I also want to keep all Comments localized in the same table though.

To note, comments don't necessarily need to know of their parents, the parent will just have a one-to-many set.

I'm not sure how clearly this was explained :) We have a couple of situations that share this basic problem - Comment/Commentable best illustrates the crux of the issue.

Thanks for any assistance/advice, and thanks to the Hibernate team for such a great product.

- Bryan


Top
 Profile  
 
 Post subject: Hibernate Version
PostPosted: Thu Apr 21, 2005 11:39 am 
Newbie

Joined: Thu Apr 21, 2005 11:11 am
Posts: 5
Location: Boston, MA
Of course I forgot to include that I'm using Hibernate3 if that makes a difference.


Top
 Profile  
 
 Post subject: no subclassing
PostPosted: Fri Apr 22, 2005 3:50 am 
Beginner
Beginner

Joined: Thu Apr 21, 2005 5:37 am
Posts: 45
Location: Switzerland
I think you said it yourself:
Quote:
To note, comments don't necessarily need to know of their parents, the parent will just have a one-to-many set.

Just make it a one-to-many set and NOT a subclass! Your Java objects (Article, Discussion) will just have a Set/List/Collection of Comments. You don't need to subclass the Comment. I think you could even share the commentableId-Row in the table of the Comment. But you don't need an attribute in the Comment-class for that row.


Top
 Profile  
 
 Post subject: Re: no subclassing
PostPosted: Fri Apr 22, 2005 8:42 am 
Newbie

Joined: Thu Apr 21, 2005 11:11 am
Posts: 5
Location: Boston, MA
keule wrote:
Just make it a one-to-many set and NOT a subclass! Your Java objects (Article, Discussion) will just have a Set/List/Collection of Comments.


If I understand what you're suggesting, I think it will only work if a common ID generator is used for everything that could have a Comment attached (Article, Discussion). Currently we're using sequences for primary key generation, but if we move to mysql and start using identity columns things would break down. In that case I think we'd need a discriminator (and subclasses of Comment?) to differentiate which 'id space' we're referring to with the foreign key back to the parent.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 22, 2005 9:19 am 
Senior
Senior

Joined: Mon Apr 04, 2005 8:04 am
Posts: 128
Location: Manchester, NH USA
What is your navigation pattern? Do you ever want to navigate backwards from a Comment to the parent object, e.g. Article? Or are you always navigating in the manner that the previous poster suggested would befit a one-to-many collection, from the Article/Discussion to related Comments?

If you were navigating backwards, I would guess (haven't tried it) that you could set up a many-to-one relationship from Comment --> Content. When you resolve that reference, the instance of Content you'd get would be the proper subclass, based on the ID that was stored - I would guess Hibernate would transparently load the proper subclass of Content for you.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 22, 2005 9:41 am 
Newbie

Joined: Thu Apr 21, 2005 11:11 am
Posts: 5
Location: Boston, MA
pmularien wrote:
What is your navigation pattern? Do you ever want to navigate backwards from a Comment to the parent object, e.g. Article? Or are you always navigating in the manner that the previous poster suggested would befit a one-to-many collection, from the Article/Discussion to related Comments?


We can get away without needing to navigate from the Comment to the parent object - it's a less common usage scenario that we can get around using straight SQL.

I think the crux of the problem is this:

Say we have articles with the following ids:
[10, 11, 12]
And discussions with the following ids:
[10, 11, 12]

There's overlap because they came from a different ID generator, so you need a discriminator in the Comment table indicating which type the foreign key represents:
Code:
[CommentID | ParentID | Discriminator | CommentText]
     10          10          ART          Blah...
     11          11          ART          Blah...
     12          10          DIS          Blah...
     13          12          DIS          Blah...


In this case the ids overlap because they were generated off of different sequences or identity columns. "Move to a shared id space" you might say. But ideally we'd like to be able to have this work across objects implementing an interface - Commentable. So we could have a shared id space for everything implementing Commentable.
But what if we also have an identical situation with other child objects - Tags that can be applied to anything that's Taggable. Then you'd need a shared id space for both Taggable and Commentable objects, which sounds like GUIDs to me, which I don't want to be forced into.

Thanks for the suggestions so far, but it is still looking to me like I'm going to have to choose between GUIDs or a bunch of subclasses for Comment (and other analogous situations).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 22, 2005 9:49 am 
Senior
Senior

Joined: Mon Apr 04, 2005 8:04 am
Posts: 128
Location: Manchester, NH USA
Why not use an Any relationship? The any will encode the class name and ID in two columns in the database, and would be represented in your class as returning an Object.


Top
 Profile  
 
 Post subject: <any> helps a lot
PostPosted: Mon Apr 25, 2005 1:48 pm 
Newbie

Joined: Thu Apr 21, 2005 11:11 am
Posts: 5
Location: Boston, MA
pmularien wrote:
Why not use an Any relationship? The any will encode the class name and ID in two columns in the database, and would be represented in your class as returning an Object.


Awesome. That pretty much solves things. The <any> helps the mapping from the Comment to the parent class. On the parent class' set mapping I can then add a static where attribute specifying the correct discriminator, or use a filter and set a parameter programmatically at runtime.

I haven't used <any> yet, and just remember that it was discouraged in Hibernate In Action because you can't ensure referential integrity without foreign key constraints. But it turns out to work well in this situation.

Thanks for the help!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.