-->
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.  [ 31 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Mapping of inheritance hierarchy
PostPosted: Tue Nov 04, 2003 3:49 pm 
I have experimented with the mapping of inheritance hierarchies in Hibernate. Below are my findings, can someone please tell me if they are correct?

1. Hibernate allows only either table-per-class-hierarchy (i.e. <subclass>) mapping or table-per-subclass mapping (i.e. <joined-subclass>) but no mixture.
2. Hibernate does not support switching between the two modes further down in the class hierarchy.
3. Hibernate does not support discriminators in conjunction with table-per-subclass mapping.


Top
  
 
 Post subject: 3
PostPosted: Tue Nov 04, 2003 4:05 pm 
Senior
Senior

Joined: Sun Aug 31, 2003 3:14 pm
Posts: 151
Location: Earth (at the moment)
I don't know about the first two but for number 3 I don't think the discriminator serves a purpose if you have seperate tables. There is no need for a discriminator to tell between different types in the same table because each has its own table.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 04, 2003 4:11 pm 
That depends on how you map: suppose the root class is mapped to one table and each subclass to a separate table; that way, you can have references to the root class. If you then have 50 subclasses, determining the class of a particular row can become very inefficient because you have to check each of 50 tables for a corresponding row. This could happen for example of you do a polymorphic query on all rows in the root table.


Top
  
 
 Post subject:
PostPosted: Tue Nov 04, 2003 8:09 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
And, if you do use the discriminator, loading the sublcass requires a sequential read per instance and immediately exposes you n+1 selects problems. So the huge-outer-join is probably preferrable anyway.

Solution: don't overuse inheritance in ORM.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 05, 2003 12:00 pm 
Firstly, since you seem to be on the Hibernate team, can you confirm my original findings? The reason I am asking is that we have a fairly large inheritance hierarchy (it is appropriate in this particular case) and would like to mix table-per-class-hierarchy with the table-per-subclass mapping. We hope to minimize the number of tables and the number of unused columns per table.

Secondly, I don't understand why there would be a problem with using the discriminator:
If the exact class is known in advance, there is no problem anyway. When doing a polymorphic query, things get a little more difficult (and inefficient), but I would expect the discriminator makes things easier. I guess you mean the two most simple approaches that can be used here: either an additional select per instance where applicable or an outer join over all involved tables to begin with. I would expect the second option to degrade badly as the number tables increases, whereas the first one is somewhat slower with a small number of tables.


Top
  
 
 Post subject:
PostPosted: Wed Nov 05, 2003 8:09 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Your original post was correct.

As to efficiency, you are correct in the case of doing a load by id - a discriminator would help. But in the case of a query with multiple results, the way Hibernate does it degrades much more gracefully.

There is no really good way to map huge inheritance structures if you need polymorphism.

If I were you, I would carefully decide exactly how far up your inheritance hierarchy you really need polymorphism.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 06, 2003 1:45 pm 
Hm, in that case I am not sure it makes sense for us to use Hibernate. The reason is that many of our classes have only one additional attribute, so table-per-subclass doesn't make much sense for them. But there is also a bunch that have many columns, so that table-per-class-hierarchy is not such good idea for them. I thought about using aggregation to get around this, but that seems cludgy.
Do you know if the are any efforts to unify the table-per-class-hierarchy with the table-per-subclass mapping?


Top
  
 
 Post subject:
PostPosted: Thu Nov 06, 2003 7:55 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
I'm not sure this is clear :
- hibernate cannot use table-per-class-hierarchy AND table-per-subclass for the SAME hierarchy
- hibernate can use table-per-class-hierarchy AND table-per-subclass for DIFFERENT hierarchies

probably obvious, but I'm not sure you got it

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 07, 2003 10:08 am 
It is obvious and I got it. That is why I ask about unifying those two approaches so that they can be used within a single hierarchy.


Top
  
 
 Post subject: Hibernate, JDO and large class hierarchies
PostPosted: Thu Nov 20, 2003 12:15 pm 
Newbie

Joined: Thu Nov 06, 2003 8:28 am
Posts: 8
I have a rather large (broad) class hierarchy where the base class is extended by a dozen other classes, each adding a dozen fields (see below for the rational behind this).

If I would use one table for all classes, this table would not only be a monster (100+ columns), but I would also run into trouble with fields from different subclasses having the same name.
Using a table per subclass approach leads to one-page-long join queries.

Until recently, I used KODO JDO to persist everything and I noticed that they use the 'discriminator approach' as mentioned earlier in this topic: (one query to determine the actual class and one query to fetch the subclass fields).
The nice thing here is that with JDO you can lazy-load all fields of the subclasses by specifying "default-fetch-group=false". Since 90% of the time I'm only accessing the fields of my base class (listings etc.), the second query isn't executed often and I get the best overall performance.

I don't see any reason to use the table-per-subclass approach unless it is implemented like described above. So I would like to know the opinion of the Hibernate team about this and also if there are plans towards JDO compliance (and hence implementing lazy loading for any field).


Ivo

PS: my use case:
I'm dealing with descriptive metadata for various types of documents (articles, web pages, graphics...). The Record class is the base class that holds the description, creation date... Type specific fields are kept in subclasses (e.g. Article has an author, Graphic has a size ...).
The different types and their fields are defined in a configuration file (xml) and the classes are generated with a Velocity template. This means that I have an arbitrary number of subclasses and fields.

I've just migrated from KODO JDO to Hibernate. The good things in Hibernate are the much better query language and the fact it is based on getters/setters instead of fields. The table-per-subclass implementation can however be improved in my opinion.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 12:30 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
I've thought about this a bit in the past....

It *really* depends upon what you are doing. Our approach is very much more efficient and elegant than the discriminator approach chosen by most JDO vendors for some kinds of problems (particularly for the simple cases).

But for very large numbers of subclasses, and for some usage patterns (such as the one you just described, where the subclasses are rarely used), the discriminator approach may be better.

Like I said, it depends a lot upon what you are doing. I'm not sure if anyone out there supports both approaches.

I recognize that this is one (perhaps the only significant) advantage of the JDO StateManager model compared to our proxy model. (However, I also recognize a bunch of huge disadvantages of the StateManager model.)
The requirement for StateManager + bytecode enhancement will be removed from the JDO2 spec, so we do not plan to redesign Hibernate to support this model.

(You *could* consider table-per-concrete-class for this, by the way. Or, you could consider using a one-to-one association instread of inheritance.)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 12:51 pm 
It seems I am not the only one who has an issue with the current class hierarchy mapping in Hibernate. Let me therefore elaborate on what I think is wrong with the current approach taken by Hibernate.

I agree that a good class hierarchy is flat and wide, i.e. having many diverse subclasses is desired because then you get a lot of reuse. Some of these subclasses will have a lot of data while others will just have different behavior. And this is exactly where the Hibernate approach becomes problematic:

- Mapping the entire hierarchy to a single table it not good because you can end up with too many columns. This makes the table hard to administrate and one may even hit RDBMS limits.

- Mapping every class in the hierarchy to a different table is not good either because there will be many tables that have only a single primary key column (for those classes that differ only in behavior).

- I think that having two different mapping modes in the descriptor (<subclass> and <joined-subclass>) is problematic by itself because both do the same thing: map a class hierarchy.

The ideal class hierarchy mapping approach would let me map class attributes as needed, i.e. subclasses with no or few additional attributes go to the main table of the hierarchy, while subclasses with many attributes will be mapped to a separate table. Sometimes several more subclasses will mapped to the separate table.

My suggestion to achieve this with Hibernate is as follows:

1. Subclass mappings always require a discriminator.

2. The subclass mapping element is enhanced to allow the table to be specified.

3. This probably makes the <joined-subclass> element obsolete.

4. Maybe it should be considered moving the <subclass> tag from the mapping file of the root class to the mapping files of the individual subclasses. This would probably make generation with XDoclet easier. It would also allow the addition of a new leaf subclass without access to the orginal source code or changes to the root mapping file. This seems a more object-oriented approach to me because why should the root of a class hierarchy have to know about all it subclasses?

I would appriciate any feedback on this matter.


Top
  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 1:01 pm 
It seems that Gavin wrote his reply at the same time as I mine, so I didn't see it. In the light of his statements want to modify my suggestion:

- If there is a good reason for keeping it (performance), the maybe the <joined-subclass> should stay.

- My real issue is more flexibility in the mapping of class hierarchies. Sure, I can always do aggregates or composites and use table-per-hierarchy, but if I only do this because of my object-relational mapper is looks like a weakness of the mapper to me. Plus in my current project it also means a significant amount of work in other places to deal with the composites.


Top
  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 1:02 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Quote:
1. Subclass mappings always require a discriminator.



No way. this is an intrusion upon the relational model that your data modeller would not understand. It is required only because of the mechanics of ORM. (Having it as an *option* is a different matter, and has, in fact been proposed in the Road Map for 2.2.)

Quote:
2. The subclass mapping element is enhanced to allow the table to be specified.

3. This probably makes the <joined-subclass> element obsolete.



And break everyone's existing applications?? No Way.

Quote:
4. Maybe it should be considered moving the <subclass> tag from the mapping file of the root class to the mapping files of the individual subclasses.


This is already possible.


Now, there is some truth to what you say, but it is far from the whole truth. There is no good, efficient way to map very large inheritance hierarchies in ORM. The n+1 selects that you get with the discriminator approach basically makes polymophic querying a no go, unless you are only going to access superclass properties (which is not really very polymorphic).

Really, there is no magic bullet here. All approaches have tradeoffs.

As I said though, we already (tentatively) propose to add support for freely mixing <subclass> and <join> elements in 2.2, which gives you what you want and much more. But this will be quite a bit of work.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 1:06 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
ick i mean to say freely mixing <subclass> and <sequential-read>.


Of course, the problem with this is that we don't have a good way to lazy load just a "piece" of the class, not without buildtime bytecode enhancement.

So I'm really not convinced about all this.


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