-->
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.  [ 2 posts ] 
Author Message
 Post subject: Suggestions, please, for mapping of complicated heirarchy?
PostPosted: Sat Nov 19, 2005 3:23 pm 
Regular
Regular

Joined: Sat Nov 19, 2005 2:46 pm
Posts: 69
I have an interesting situation with trying to map a class heirarchy, and can't seem to find the best solution for it. I was using hibernate 2.0, but have upgraded to 3.0 as there appears to be more flexibility with its mappings.
I have two tables like so:
Code:
+---------------+
|template       |
+---------------+
| id    int     |
| type varchar  |
| other data... |
+---------------+
     /\
     ||
+-----------------+
| instance        |
+-----------------+
| id int          |
| template_id int |
| other data...   |
+-----------------+

And I have this java class heirarchy:
Code:
AbstractTemplate  ==> TypeATemplate
||               ==> TypeBTemplate
||               ==> TypeCTemplate
\/
AbstractInstance  ==> TypeAInstance
                  ==> TypeBInstance
                  ==> TypeCInstance


Basically, instances relate to templates as one-to-many, and I wanted instances to subclass templates as there properties and associations on the template which I want the instance to have too.
I've been trying to map this as table-per-subclass strategy.
But the concrete template types, and the concrete instance types, I wanted them all to switch on the same discriminator, which is the "type" column in the "template" table.
I've tried several combinations of <class> <subclass>, <join>, <joined-subclass> and use, or not, of <discriminator> for these 8 classes (2 abstract, 6 concrete)

The best I came up with was:
Code:
<class name="AbstractTemplate" table="template">
  <id name="id" column="id"><generator class="native"/></id>
  <discriminator column="type"/>
  <property ..(many of).. />

  <subclass name="TypeATemplate" discriminator-value="A"/>
  <subclass name="TypeBTemplate" discriminator-value="B"/>
  <subclass name="TypeCTemplate" discriminator-value="C"/>

  <subclass name="AbstractInstance">
    <join table="instance" fetch="select">
      <key column="template_id"/>

      <property ..(many of)../>
      <subclass name="TypeAInstance" discriminator-value="A"/>
      <subclass name="TypeBInstance" discriminator-value="B"/>
      <subclass name="TypeCInstance" discriminator-value="C"/>
    </join>
  </subclass>
</class>

With this, things are almost working, and all the templates are happliy mapped. But the instances - when loading them, instead of hibernate finding each one, it finds the first of each (according to template's id value) duplicated by the number of each in the database (in the instance table).
What I think I need is for AbstractInstance to map its own id value, which means it needs to be a class, not a subclass, with the AbstractTemplate being a mapped association - but then how do I switch on the discriminator?
Is the solution just to have a duplicate discriminator in the instance table? (The rows in "instance" are generated with reference to "template")

I also considered changing the heirarchy to that TypeAInstance subclasses TypeATemplate, and AbstractInstance becomes just an interface (in C++ I would have used multiple-inheritance) but I'm not keen to do this, as there's a fair portion of code in AbstractInstance which would have to be duplicated within each concreate TypeXInstance.

Any suggestions?

Cheers,

_________________
Stewart
London, UK


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 20, 2005 9:44 am 
Regular
Regular

Joined: Sat Nov 19, 2005 2:46 pm
Posts: 69
Here is the solution that I came up with eventually.
I read many posts and much documentation in my journey to this solution, and it's a shame credits can't be awarded retrospectively when someone's post proves useful to others later.

This the first thing was to realise that the "instance" classes should not be subclasses of the template class. This is like saying a tyre is a subclass of a tyre-mould. It isn't - wet-grip and dry-grip would be subclasses of tyre, and wet-grip-mould and dry-grip-mould are subclasses of tyre-mould.
Just because a tyre derives properties (tread-depth) from its mould, doesn't make it a subclass. I was using subclassing to save code duplication, but lost site of correct OO modelling.
What I did now is that the instance has a many-to-one association to the template, and then I wrapped/decorated the properties:
Code:
public class Instance // extends Template // drop the extends!
{
  private Template template;

  public String getProperty()
  {
    return template.getProperty();
  }
.....


This solved half of it. TypeA, B, C subclasses switching on the discriminator is solved by using
Code:
<discriminator formula="SELECT type FROM template t WHERE t.id = template_id"/>

for the mapping of the instance class.

And now we're happy :-)
Let's see now, where's the link to award myself a credit for this?

_________________
Stewart
London, UK


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