-->
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 With Different Parents Classes
PostPosted: Fri Apr 20, 2007 12:52 am 
Newbie

Joined: Fri Apr 20, 2007 12:35 am
Posts: 3
Hi,

What's the best practice for creating parent-child / one-to-many relationships where the child table has only one parent, but that parent could be one of any number of classes?

Example Structure:

Child Table:
id
data
parent_id
parent_type

Parent Tables:
ParentType1:
id
data

ParentType2:
id
data

ParentType3:
id
data

The one-to-many relationship would only be declared on the parent side of things.

Example Usage:

CRM system with Accounts, Contacts, and Projects tables (possible parents). Each of these entities can store Notes (the child table). The Notes table has parent_id and parent_type fields. So, for Accounts Nots, parent_type='Accounts' and parent_id='id of account'.

This is actually how a number of open-source CRM systems store notes for various entities.

I'm wondering if there's a "mapping" kind of way to represent these relationships. I've read A LOT of stuff (still a noob) but can't seem to find anything that describes this in a way I'm recognizing :)

Ruby on Rails allows this kind of relationship through "conditions". e.g.,

class Accounts
has_many :notes, :conditions=>"parent_type='Accounts'"
end


Thanks!


Shawn


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 26, 2007 12:00 am 
Newbie

Joined: Fri Apr 20, 2007 12:35 am
Posts: 3
Bump....not a critical question - just curious.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 27, 2007 12:05 pm 
Newbie

Joined: Mon Apr 02, 2007 12:31 pm
Posts: 19
To do what you describe, you can use NHibernate's polymorphism mechanisms and a few special mapping elements. The child table needs to have the following mapping:

<any name="Parent"
meta-type="class"
id-type="Int64"> <!--the type you're using for your id's-->
<column name="parent_type"/>
<column name="parent_id"/>
</any>

The dbType of the parent_type column needs to be pretty long (I usually use 250 characters) because it holds a fully-qualified class name.

All parents should implement an interface you define (maybe called IHasNotes). Then the child.Parent property can be of type IHasNotes. The IHasNotes interface defines a collection of the child objects mapped in the usual way:
<set name="Notes" inverse="true">
<key column="note_id"/>
<one-to-many class="Notes"/>
</set>

You should look at the NHibernate documentation for Inheritance Mapping strategies. This example uses the third strategy, table-per-concrete-class. There are various things to consider for each of the three inheritance strategies, and you may be better off with one of the other two.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 01, 2007 9:15 am 
Beginner
Beginner

Joined: Thu Apr 19, 2007 5:37 am
Posts: 28
JWLato wrote:
All parents should implement an interface you define (maybe called IHasNotes).


Unfortunately, with this strategy, it seems like you will have to have a public id field (or property) as to map a class, you need an id, and interfaces are public only.

I am facing this kind of issue, and it seems like I will have to go the route I was trying to avoid: create an abstract class, and derive from it.

This is obviously a big issue since I won't be able to derive my classes from any other classes in the future, so I am wondering if I won't regret it somewhere down the road...

Seems like another case where Hibernate is not so much transparent to the way you develop your classes... :-(

Any advice would be welcome.


Top
 Profile  
 
 Post subject: Re: One-to-Many With Different Parents Classes
PostPosted: Tue May 01, 2007 10:17 am 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
Disclaimer: Not aware of a well-defined best practice, and haven't tried/tested this:


How about having a child implementation/inheritor for each parent? With interfaces, might look like this:

mapping might be something like this
Code:
<class name="INote" ... >
  <id name="id" ...>...</id>
  <discriminator column="parent_type"/>
  <property name="data" />

  <subclass name="type1note" discriminator-value="type1" ...>
    <many-to-one name="Parent" class="type1" column="parent_id" />
  </subclass>

  <subclass name="type2note" discriminator-value="type2" ...>
    <many-to-one name="Parent" class="type2" column="parent_id" />
  </subclass>
...
</class>


Parent mapping would be

Code:
<class name="Type1">
  <id name="id"...>...</id>
  <property name="data"/>
  <[collection] name="Notes" inverse="true"...>
    <key column="parent_id" />
    <one-to-many class="type1note" />
  </[collection]>
</class>


That should do you very nicely, retaining your underlying table structure.

Again, not tried/tested, so YMMGV. Abstract note base might be better, too, for reuse of things that won't change.

Good luck!

-Marc


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 02, 2007 5:16 pm 
Newbie

Joined: Mon Apr 02, 2007 12:31 pm
Posts: 19
Pejvan spake:
Quote:
Unfortunately, with this strategy, it seems like you will have to have a public id field (or property) as to map a class, you need an id, and interfaces are public only.


I don't believe this is true for the table-per-concrete-class strategy. The mapping doesn't mention the interface at all, so NHibernate technically doesn't know about it. When an object with IHasNotes is persisted, NHibernate uses the object's class to identify it, not the interface. I have a project with several classes mapped using this strategy and the interface doesn't include the Id, so I know it works for at least some cases.


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.