-->
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.  [ 4 posts ] 
Author Message
 Post subject: Mapping a class to a lookup table
PostPosted: Thu Mar 23, 2006 6:55 am 
Beginner
Beginner

Joined: Sat Mar 04, 2006 1:07 am
Posts: 27
Hibernate version:
3.1

I have a class called RecordStatus with the following
attributes

Code:
public class RecordStatus {
   private Long id;
   private String status;
   private String statusDescription;
   private String statusReason;
   private String statusReasonDescription;
   private Date statusDate;

}



I have a legacy table called Lookup which has a foriegn key (LOOKUP_CAT_ID) into a LookupCategory table. The status and statusReason attributes above are represented as separate LookupCategory table entries with the statusDescription and statusReasonDescription attributes occurring in the Lookup table (with status as the foriegn key). An example of the Lookup table is as follows

Code:
LOOKUP_ID   LOOKUP_CAT_ID         LOOKUP_VAL    LOOKUP_DESC
1           recordStatus          A             statusDescriptionA
2           recordStatus          B             statusDEscriptionB
3           recordStatusReason    C             statusReasonDescriptionA
4           recordStatusReason    D             statusReasonDescriptionB


One can have the same recordStatusReason for different recordStatus entries and they are maintained separately.

Each instance of the RecordStatus class only has one combination of status and statusReason but I'm not sure if and how this can be mapped? I can change or break up RecordStatus if necessary.

Any suggestions?
Thanks
Alan


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 24, 2006 12:06 am 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
First, it will be much easier to have RecordStatus defined like this:
Code:
public class RecordStatus {
  private Lookup statusLookup;
  private Lookup statusReasonLookup;
}
If you want RecordStatus to have getStatus(), getStatusDescription(), etc. methods, then do that using delegation.

I suggest forgetting about the status/statusReason combination constraint in the mapping, and just have two many-to-one relationships from RecordStatus to Lookup. Then enforce the constraints in business logic. This is the simpler and more maintainable solution.

It is possible to have hibernate do this for you, at least in Hibernate3+. It's a bit involved:

- Create StatusLookupImpl and StatusReasonLookupImpl classes: these won't be directly referenced in your app, just in your mapping. You'll be using the Lookup interface throughout your app (and these classes will implement it).

- Use the <subclass> element to describe StatusLookupImpl and StatusReasonLookupImpl as subclasses of LookupImpl (which also implements the Lookup interface).

- Use the where="" attribute in any classes that refer to Lookup objects (presumably, just the RecordStatus class) specify that a particular set uses just StatusLookupImpls or just StatusReasonLookupImpls.

Like I say, it's a bit involved, and definitely requires more work to maintain, hence the recommendation to enforce that constraint in java code. I use this solution in my own apps, though, and it is quite effective.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 24, 2006 10:38 pm 
Beginner
Beginner

Joined: Sat Mar 04, 2006 1:07 am
Posts: 27
Thanks again. Another credit coming your way!

I assume the Lookup interface will specify the getter and setters for the Lookup table attributes?

Also, I'm not clear on the mapping file. Is it in the RecordStatus mapping file that the 2 subclasses (StatusLookupImpl and StatusReasonLookupImpl) be defined? The where attribute can only be specified on the class, so will it look like this:
Code:
<class name="RecordStatus" mutable="false" table="LOOKUP" where="lookup_cat_id = 'recordStatus or lookup_cat_id = 'recordStatusReason'">


I'm a bit confused

Regards
Alan


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 26, 2006 6:37 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
On re-reading your earlier posts, I find myself confused, because I can't find a reference to a RecordStatus table anywhere. It looks like you're hoping to map two rows from one table into one mapped object. I'll go on with my explanation assuming that there is a RecordStatus table somewhere, and it just hasn't been mentioned yet. If there really isn't a table with two associations to your Lookup table (one for status and one for statusReason), then I'm pretty sure that there's no way to map a RecordStatus object. Anyway...

alankstewart wrote:
I assume the Lookup interface will specify the getter and setters for the Lookup table attributes?

The Lookup implementation class will specify those getters and setters. You don't have to provide a Lookup interface if you want the API user to use only RecordStatus: I'd probably recommend having a Lookup interface with at least the getters.

alankstewart wrote:
Is it in the RecordStatus mapping file that the 2 subclasses (StatusLookupImpl and StatusReasonLookupImpl) be defined?

No, you use the LookupImpl class to be the parent of the two "real" impl classes. You could start with this mapping, then tailor it for your exact values:
Code:
<class name="LookupImpl" table="Lookup" mutable="false" discriminator-value="null">
  <id name="LookupID" ...>
    ...
  </id>
  <discriminator column="LOOKUP_CAT_ID" type="string"/>

  <many-to-one name="Category" class="LookupCategoryImpl" column="LOOKUP_CAT_ID"/>
  <property name="Description" type="string" column="LOOKUP_DESC"/>

  <subclass name="LookupStatusImpl" discriminator-value="recordStatus"/>
  <subclass name="LookupStatusReasonImpl" discriminator-value="recordStatusReason"/>
</class>

<class name="RecordStatus" mutable="false" table="RecordStatus">
  <id .../>

  <many-to-one name="Status" class="LookupStatusImpl" column="StatusId"/>
  <many-to-one name="StatusReason" class="LookupStatusReasonImpl" column="StatusReasonId"/>
</class>
If you need to map a collection of Status or StatusReason objects, that's where the where attribute comes in:
Code:
<set name="Statuses" where="recordStatus">
  <key column="ParentId" not-null="true"/>
  <one-to-many class="LookupStatusImpl"/>
</set>

<set name="Reasons" where="recordStatusReason">
  <key column="ParentId" not-null="true"/>
  <one-to-many class="LookupStatusReasonImpl"/>
</set>


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