-->
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.  [ 10 posts ] 
Author Message
 Post subject: How to use "many-to-one" to a table with discrimin
PostPosted: Mon Jan 05, 2004 9:51 am 
Newbie

Joined: Wed Oct 08, 2003 9:27 am
Posts: 4
Location: Netherlands
Hi all,

in our project we use Hibernate 2.1 to map our fine grained, strong typed object model to a relational database (Oracle).

We have a variety of code/description classes mapped onto a single database table, each of them being a subclass of a CodeModel class distinguished by a discriminator. This works fine for reading the individual code/description classes, but to our disappointment we cannot (to our knowledge) refer to an individual code/description object from a referring object using Hibernate mapping.
As a temporary solution we read related CODE objects by hand-coded statements, but this is not what we like...

Is there a solution to this problem in Hibernate?

Below a simplified example showing how we would like to specify the mapping.
With this mapping, Hibernate has sufficient information to resolve the references.

The current problem is that in the ClientModel, there's only one attribute, whereas there are 2 fields in the PK of the MaritalStateModel. However, one field of the PK if fixed (Discriminator)

The example shows the mapping of a ClientModel class referring to a GenderModel and a MaritalStateModel, both subclasses of CodeModel.


Code:
<hibernate-mapping>

    <class name="app.model.CodeModel" table="CODE">
        <composite-id name="codepk" class="app.model.CodePKModel">
            <key-property name="prefix"/>
            <key-property name="code"/>
        </composite-id>

        <discriminator column="PREFIX" type="string"/>

        <property name="order"/>
        <property name="description"/>

        <subclass name="app.model.GenderModel" discriminator-value="GENDER"/>
        <subclass name="app.model.MaritalStateModel" discriminator-value="MARSTATE"/>
    </class>
   
    <class name="app.model.ClientModel" table="CLIENT">
        <composite-id name="clientnr" class="app.model.ClientnrModel">
            <key-property name="clientnr"/>
        </composite-id>

        <property name="name"/>
        <property name="town"/>

        <many-to-one name="gender"
             column="GENDERCODE" class="app.model.GenderModel"/>
        <many-to-one name="maritalstate"
             column="MARITALSTATECODE" class="app.model.MaritalStateModel"/>

    </class>

</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 05, 2004 1:24 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
I don't get it. Why is the discriminator part of the PK? Is your id property not enough for identifying the individual objects?


Top
 Profile  
 
 Post subject: Re: How to use "many-to-one" to a table with discr
PostPosted: Mon Jan 05, 2004 2:24 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Code:
<hibernate-mapping>

    <class name="app.model.CodeModel" table="CODE">
        <composite-id name="codepk" class="app.model.CodePKModel">
            <key-property name="prefix"/>
            <key-property name="code"/>
        </composite-id>

        <discriminator column="PREFIX" type="string"/>

        <property name="order"/>
        <property name="description"/>

        <subclass name="app.model.GenderModel" discriminator-value="GENDER"/>
        <subclass name="app.model.MaritalStateModel" discriminator-value="MARSTATE"/>
    </class>
   
    <class name="app.model.ClientModel" table="CLIENT">
        <composite-id name="clientnr" class="app.model.ClientnrModel">
            <key-property name="clientnr"/>
        </composite-id>

        <property name="name"/>
        <property name="town"/>

        <many-to-one name="gender" class="app.model.GenderModel"/>
           <column name="genderprefix"/>
           <column name="gendercode"/>
        </many-to-one>
        <many-to-one name="maritalstate" class="app.model.MaritalStateModel">
           <column name="maritalprefix"/>
           <column name="maritalcode"/>
          </many-to-one>
    </class>

</hibernate-mapping>

Note marital and gender prefix can share the same columns (it should work).

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 06, 2004 4:36 am 
Newbie

Joined: Wed Oct 08, 2003 9:27 am
Posts: 4
Location: Netherlands
Dear epbernard,

The problem with this direction is that the ClientModel with it's table does not have a gender-prefix (and marital-prefix). And it shouldn't because these prefixes are constants, just like the discriminator values in the CodeModel.

So this direction forces us to add two extra prefix-columns with fixed values for each row to our client-table.


Code from ClientModel:
Code:
       <many-to-one name="gender" class="app.model.GenderModel"/>
           <column name="genderprefix"/>
           <column name="gendercode"/>
        </many-to-one>
        <many-to-one name="maritalstate" class="app.model.MaritalStateModel">
           <column name="maritalprefix"/>
           <column name="maritalcode"/>
          </many-to-one>


So the last thing we need here is how to tell Hibernate that the two prefixes in the code above are not mapped to a physical database column, but are just constants.

What we need is something like this (not valid, this is only to illustrate our needs):

Code:
       <many-to-one name="gender" class="app.model.GenderModel"/>
           <column name="genderprefix" value="GENDER" update="false" insert="false"/>
           <column name="gendercode"/>
        </many-to-one>
        <many-to-one name="maritalstate" class="app.model.MaritalStateModel">
           <column name="maritalprefix" value="MARITAL" update="false" insert="false"/>
           <column name="maritalcode"/>
          </many-to-one>
 


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 06, 2004 12:08 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
jas wrote:
So this direction forces us to add two extra prefix-columns with fixed values for each row to our client-table.

As I tried and failzed to tell is that you can do
Code:
<many-to-one name="gender" class="app.model.GenderModel"/>
           <column name="prefix"/>
           <column name="code"/>
        </many-to-one>
        <many-to-one name="maritalstate" class="app.model.MaritalStateModel">
           <column name="prefix"/>
           <column name="code"/>
          </many-to-one>

You can share the same columns.

Of you want to have a many-to-one to a generic CodeModel then do
Code:
<many-to-one name="codeModel" class="app.model.CodeModel"/>
           <column name="prefix"/>
           <column name="code"/>
        </many-to-one>

Hibernate will be aware of the subtype of CodeModel since (prefix, code) is the PK of you CodeModel table and the dircriminator will give it the type.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 07, 2004 6:18 am 
Newbie

Joined: Wed Oct 08, 2003 9:27 am
Posts: 4
Location: Netherlands
Hi Emmanuel,

Thanks for the trouble you are taking to answer my question, but I think you are missing the key point of the problem:

We DO NOT HAVE (and don't want) any PREFIX column in the CLIENT table!

If we chose to include PREFIX , we should have two of them (for the described example, in reality we have more of them):

- column GENDER_PREFIX containing the value "GENDER" for EACH ROW!!!
- column MARITAL_PREFIX containing the value "MARITAL" for EACH ROW!!!

You see, we are simulating constants by fixed values in columns. This is not a desired solution, we would expect powerful Hibernate to come to the rescue...

In our view a solution as described in http://forum.hibernate.org/viewtopic.ph ... 65#2184465 is perfect.


Please give it another try...

Kind regards.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 07, 2004 6:32 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
eheh, I finally get it (I was considering prefix as word prefix, not prefix column).
You can't do such a thing: update insert = false are just here to prevent sql generation, so the structural concepts (2 column FK) remains. I don't know how to do what you want, and for sure it would be a really dirty Hibernate hacking to allow that.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 07, 2004 9:48 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
BTW, why not using an HQL request to match you needs?

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 07, 2004 11:29 am 
Newbie

Joined: Wed Jan 07, 2004 11:16 am
Posts: 2
Location: Netherlands
Hi Emmanuel,

I am a close colleague of JAS, we logged this issue together.

The construction that we described above happens frequently in our application.
The CLIENT example is a simplified case, we have a total of 5 of these references from our real CLIENT table.

Writing queries is more work than describing the mapping.
Besides the mapping acts global, so this should be the place.

I realize that our suggestion requires an extension to Hibernate, but in our humble view it is a powerful extension ;-)

As a matter in fact we could extend it even further:
we proposed a "value=" for constants, an "expression=" could contain a Java expression.

Can you consider adding it to the Hibernate feature wishlist?

Kind regards, Rob.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 07, 2004 12:03 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
I'm not the lead developper, add it to JIRA.

_________________
Emmanuel


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.