-->
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: map one-to-one association to same class
PostPosted: Thu Jul 06, 2006 4:58 pm 
Newbie

Joined: Tue Jun 27, 2006 2:51 pm
Posts: 14
Hi Guys,

This seems like it should be simple to do, yet I'm struggling. I have a class called Accessory that I would like to carry a string property of accessoryname. The issue is the table is separated such that there's an accessory table that describes its id, and then a separate accessoryDetail table to identify its name and other details, which joins back to the first table with the accessory id. As seen below, I've mapped an accessory class to have a property of type accessoryDetail. At this time, AccessoryDetail contains only a string property for the accessoryName. I want to remove the use of an AccessoryDetail class altogether and have the accessoryName be a property of Accessory. How do I do this?

I'm running on mysql

Hibernate version:
Hibernate 3.0

Mapping documents:
Code:
<hibernate-mapping package="com.mitsubishi.mmsa.hib">
   <class name="Accessory" table="mmsaBPTrimAccessoryPrice">
      
      <cache usage="read-write" region="standardCache"/>
      <id name="accessoryPriceId" column="AccessoryPriceId" type="integer">
         <generator class="native"/>
      </id>
      
      <property name="accessoryId" column="AccessoryId" type="integer"/>
      
      <many-to-one
         name="accessoryDetail" 
         column="AccessoryId"
         class="AccessoryDetail"
         insert="false"
         update="false"
      />
      
   </class>

</hibernate-mapping>
<hibernate-mapping package="com.mitsubishi.mmsa.hib">
   <class name="AccessoryDetail" table="mmsaBPModelAccessoryContent">
   
      <cache usage="read-write" region="standardCache"/>
      <id name="accessoryId" column="AccessoryId" type="integer">
         <generator class="native"/>
      </id>
      <property name="accessoryName" column="AccessoryName" type="string"/>
      
   </class>
   
</hibernate-mapping>




Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 06, 2006 10:57 pm 
Newbie

Joined: Tue Jun 27, 2006 2:51 pm
Posts: 14
I should mention I've tried looking at the join tag, it looked the most promising. I wrapped a <property> tag within a <join> tag and specified the table and key column. When I ran it, no data was returned for my mappings. I thought a component might do the trick. I've looked at entitys, but that seems to be used for re-using a class for separate tables, where as I want to essentially map a property from one table, then a few others from another table.
In thinking about this further, the workaround I can see would be to have my association mapped as a collection even though there will only be one element at any time. Then I can have a getter that essentially grabs the one element from this collection and returns it as a string or whatever type it is. This to me is a total hack, and it seems the domain model shouldn't have to be stretched in this way. Does this sound like my only alternative? Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 06, 2006 11:42 pm 
Beginner
Beginner

Joined: Tue Jun 28, 2005 2:43 pm
Posts: 29
Location: Silicon Valley
What did your attempt at using <join> look like? I agree that looks like the promising approach, and it really should work. Maybe there was some other problem in the mapping that made it return no data.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 12:22 am 
Newbie

Joined: Tue Jun 27, 2006 2:51 pm
Posts: 14
This is what my mapping looked like. When I ran it and my objects that normally held accessory objects had none list. As soon as I reverted back to my orginal mapping that uses a AccessoryDetail class, the accessory objects came back

Code:

<hibernate-mapping package="com.mitsubishi.mmsa.hib">

   <class name="Accessory" table="Accessory">
     
      <cache usage="read-write" region="standardCache"/>
      <id name="accessoryPriceId" column="AccessoryPriceId" type="integer">
         <generator class="native"/>
      </id>
     
      <property name="accessoryId" column="AccessoryId" type="integer"/>
     
      <join table="accessoryContent">
         <key column="accessoryId"/>
         <property name="accessoryName" column="AccessoryName"/>
      </join>   
     
   </class>

</hibernate-mapping>

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 1:03 am 
Beginner
Beginner

Joined: Tue Jun 28, 2005 2:43 pm
Posts: 29
Location: Silicon Valley
As written, Hibernate will try to join your tables on accessoryContent.accessoryId = Accessory.AccessoryPriceId (quick tangent: capitalization is not consistent between tables--is that intentional?). The easiest solution is to add property-ref="accessoryId" to the key element so it knows not to attempt a join on Accessory's primary key.

see http://www.hibernate.org/hib_docs/v3/reference/en/html/mapping.html#mapping-declaration-key

A different approach, which may or may not make sense in your case, would be to 'invert' the roles of the two tables, something like:

Code:
<hibernate-mapping package="com.mitsubishi.mmsa.hib">

   <class name="Accessory" table="accessoryContent">

      <cache usage="read-write" region="standardCache"/>
      <id name="accessoryId" column="accessoryId" type="integer">
         <generator class="native"/>
      </id>

      <property name="accessoryName" column="AccessoryName"/>
     
      <join table="Accessory">
         <key column="AccessoryId"/>
         <property name="accessoryPriceId" column="AccessoryPriceId" type="integer">
      </join>   
   </class>

</hibernate-mapping>


This has the advantage that the foreign key relationship is more 'natural', from a non-pk column in the joined table to the pk of the main table. Of course, it also changes the id of your aggregate object from accessoryPriceId to accessoryId, which may not be what you want, but that's up to you.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 07, 2006 11:58 am 
Newbie

Joined: Tue Jun 27, 2006 2:51 pm
Posts: 14
First off, thanks for your help on this..

I wrote out that mapping off the top of my head last night as I didn't have the actual mapping in front of me, so it might have been off a little. Exploring the join tag further this morning, I realised in my first attempt at it, I was keying off an incorrect foreign key. I resolved it, and came up with the following:

Code:
<hibernate-mapping package="com.mitsubishi.mmsa.hib">
   <class name="Accessory" table="mmsaBPTrimAccessoryPrice">
      
      <cache usage="read-write" region="standardCache"/>
      <id name="accessoryId" column="AccessoryId" type="integer">
         <generator class="native"/>
      </id>
      
      <join table="mmsaBPModelAccessoryContent">
         <key column="AccessoryId"/>
         <property name="accessoryName" column="AccessoryName" type="string"/>
      </join>
      
   </class>

</hibernate-mapping>


This works like a charm and now I can remove a few unnecessary classes from my domain model, very cool! Thanks again for your help!

- Mike


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.