-->
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.  [ 11 posts ] 
Author Message
 Post subject: hierarchical mapping without discriminator
PostPosted: Fri Sep 02, 2005 10:33 am 
Newbie

Joined: Fri Sep 02, 2005 10:25 am
Posts: 5
hi,

I'd like to know how Hibernate can, in case of hierarchical mapping, instantiate the right class if no discriminator is defined in the mapping file.

The documentation claims it does it. But I'd really to know how.

Thanks for your answer

Christophe


Top
 Profile  
 
 Post subject: Re: hierarchical mapping without discriminator
PostPosted: Fri Sep 02, 2005 11:30 am 
Beginner
Beginner

Joined: Wed Jul 13, 2005 2:18 pm
Posts: 44
christophe_grosjean wrote:
hi,

I'd like to know how Hibernate can, in case of hierarchical mapping, instantiate the right class if no discriminator is defined in the mapping file.

The documentation claims it does it. But I'd really to know how.

Thanks for your answer

Christophe


The magic of implicit polymorphism =) I was really blown away the first time I tried this, it's a neat feature.

Let's say you've got a table-per-concrete class situation, where you've got an Employee and a Student table (I just finished a project in which we had *exactly* this scenario - the app ran off of our data warehouse) which contain some common data, like name and social security number, and also some data specific to employees or students respectively. Even though the fields are duplicated in the tables, it would be a shame to duplicate them (and any logic associated with them) in your Java classes. So what you do is create a base class 'Person' which has properties for the fields which the two tables share. Then you create 'Employee' and 'Student' objects which extend the 'Person' object and add additional appropriate properties and business logic. You create a hibernate mapping file for the two subclasses - Employee and Student.

And that's it.

If you want to retrieve a list of Students and employees, you can use the following HQL query: "from Person". Hibernate will query both the employee and student tables, and give you back a mix of Employee and Student objects, even though you never created a mapping file for Person. Very cool stuff.

_________________
- Matt


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 02, 2005 11:41 am 
Newbie

Joined: Fri Sep 02, 2005 10:25 am
Posts: 5
Thank you for your answer.

But in fact, in other words, my question is :

From a result set contains rows about Employee and Student, how can hibernate know that it has to instantiate an Employee or a Student ?

With discriminator, it's obvious... but here...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 02, 2005 11:54 am 
Newbie

Joined: Fri Dec 17, 2004 2:38 pm
Posts: 11
Location: Buenos Aires
christophe_grosjean wrote:
Thank you for your answer.

But in fact, in other words, my question is :

From a result set contains rows about Employee and Student, how can hibernate know that it has to instantiate an Employee or a Student ?

With discriminator, it's obvious... but here...


Prehaps it helps you.

This is a query generated by hibernate where I've:

Exception (Abstract on mapping)
--- ExpirationException
--- ProcessException (Abstract on mapping)
--- CotaException
--- ExclussionException


SELECT
this_.ID as ID0_,
this_.EXCEPTION_RULE as EXCEPTION2_1_0_,
this_.JUSTIFICATION as JUSTIFIC3_1_0_,
this_.VIGENCIA_DESDE as VIGENCIA4_1_0_,
this_.VIGENCIA_HASTA as VIGENCIA5_1_0_,
this_.ID_CAUSE as ID6_1_0_,
this_.TO_DATE as TO1_2_0_,
this_.GENERAL_EXP_DATE as GENERAL2_2_0_,
this_.clazz_ as clazz_0_
FROM
(
select nullif('x',
'x') as TO_DATE,
ID_CAUSE,
JUSTIFICATION,
VIGENCIA_DESDE,
VIGENCIA_HASTA,
nullif('2000-1-1',
'2000-1-1') as GENERAL_EXP_DATE,
EXCEPTION_RULE,
ID,
3 as clazz_ from EXCEPCION.EXCLUSION_EXCEPTION_ENTITY
union all
select nullif('x',
'x') as TO_DATE,
ID_CAUSE,
JUSTIFICATION,
VIGENCIA_DESDE,
VIGENCIA_HASTA,
nullif('2000-1-1',
'2000-1-1') as GENERAL_EXP_DATE,
EXCEPTION_RULE,
ID,
4 as clazz_ from EXCEPCION.COTA_EXCEPTION_ENTITY
union all
select TO_DATE,
ID_CAUSE,
JUSTIFICATION,
VIGENCIA_DESDE,
VIGENCIA_HASTA,
GENERAL_EXP_DATE,
EXCEPTION_RULE,
ID,
1 as clazz_ from EXCEPCION.EXPIRATION_EXCEPTION_ENTITY ) this_


As you can see, Hibernate put and clazz_ column where put a number (1, 4 or 3) depending on the subclass it is querying on.

YOu cant see a query to Exception or ProcessException because they are abstracts on mapping.

I think it's used to discriminate the class to be instanciated.

I hope it helps

Regards

German.-


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 02, 2005 12:07 pm 
Beginner
Beginner

Joined: Wed Jul 13, 2005 2:18 pm
Posts: 44
christophe_grosjean wrote:
Thank you for your answer.

But in fact, in other words, my question is :

From a result set contains rows about Employee and Student, how can hibernate know that it has to instantiate an Employee or a Student ?

With discriminator, it's obvious... but here...


The key is that in the case I described, the two subclasses are mapped to different tables, so a discriminator is entirely unnecessary. Hibernate queries both tables. Objects from the student table are instantiated as Student objects, objects from the employee table are instantiated as Employee objects.

If you need to map your whole heirarchy to a single table, then you probably don't want to rely on implicit polymorphism.

_________________
- Matt


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 05, 2005 9:05 am 
Newbie

Joined: Fri Sep 02, 2005 10:25 am
Posts: 5
Ok. Thank you for your examples.

I know understand the "magic" behind it.

Regards,
Christophe


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 13, 2005 2:26 pm 
Newbie

Joined: Tue Mar 08, 2005 5:05 pm
Posts: 9
That is pretty cool. Now the follow up question (I think I know the answer but I'm hoping I'm wrong): is there a way to define the person part of the mapping in a seperate hibernate map so that you don't have to explicitly list the shared data fields in both the employee and student mappings? In other words right now you do this:

Java:
class person (name)
class employee extends person (employeenum)
class student extends person (studentid)
Hibernate
<class name=employee><properties name, employeenum></class>
<class name=student><properties name, studentid></class>

But is there some way to say:
<class name=person><properties name></class>
<class name=employee><properties person, employeenum></class>
<class name=student><properties person, studentid></class>

So if we added a property to person we wouldn't have to update all the mappings based on it?

Thanks in advance
Sean


Top
 Profile  
 
 Post subject: Just a case of mapping them as joined subclasses?
PostPosted: Tue Sep 13, 2005 8:04 pm 
Newbie

Joined: Sun Apr 10, 2005 9:35 pm
Posts: 14
Hi Sean,

In order to do this:
Quote:
Java:
class person (name)
class employee extends person (employeenum)
class student extends person (studentid)

Surely all you need to do is create the hibernate mapping so that both Employee and Student are subclasses of Person? Depending on how much data they have in common the table-per-class-hierarchy might be suitable. Alternatively, there's the table-per-subclass strategy.

Hope this helps.

Mike


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 13, 2005 8:45 pm 
Newbie

Joined: Tue Mar 08, 2005 5:05 pm
Posts: 9
Thanks Mike thats kind of what I was thinking but I wasn't able to find a configuration that allowed it (unfortunately I'm not at the office right now so I can't check). What I was hoping was that I could find a way to do something like:

person.hbm.xml
<class><property name"name"/></class>

then

employee.hbm.xml
<subclass extends="person" table="employee">
<property name="empid"/>
</subclass>

And have just one table (employee with columns name and empid) that would be perfect but I can't seem to figure out the mappings to pull that off. Any pointers (or sample configs) would really be appreciated. I'm sure there's someway to do it but the summer seems to have fried my brains :)


Top
 Profile  
 
 Post subject: Subclass mappings
PostPosted: Wed Sep 14, 2005 5:39 pm 
Newbie

Joined: Sun Apr 10, 2005 9:35 pm
Posts: 14
Hi Sean,

The mapping you're looking for is really quite straightforward. Just have a look through the hibernate docs and keep an eye out for the <subclass> or <joined-subclass> elements in the mapping section.

Mike


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 14, 2005 6:09 pm 
Newbie

Joined: Tue Mar 08, 2005 5:05 pm
Posts: 9
Thanks again Mike but I must be an idiot or something as I can't figure out a way to get a config that does what I want. From the docs what I'm looking for is a table per concrete class (section 10.1.5) but unfortunately there's a couple problems with it

1. Can't use identity for the id generator (my tables are preset so I can't change that)
2. can't define union-subclass in their own mapping files (dtd only allows class, subclass and joined-subclass)

Ah well, it was close but I guess just not meant to be unless I can redo the tables (not gonna happen). What I've got to work with is the equivalent of:

Tables:
employee
[id (autoincr)][name][empid]
studentid
[id (autoincr)][name][studentid]

Files:
person.java + person.hbm.xml (id + name)
employee.java + employee.hbml.xml (extend person, add empid)
student.java + student.hbml.xml (extend person, add studentid)

Thanks again Mike, appreciate it.


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