views:

747

answers:

4

I need to map two tables to a single class, having trouble figuring this out. One table is ROOMS, the other is TRAINERS.

The ROOMS table:

OOC_UNIT_ID          NUMBER(6,0)
OOC_START_DT         DATE
OOC_START_TM         DATE
OOC_DT_MOD           DATE
OOC_USER_MOD         VARCHAR2(30 BYTE)
OOC_END_DT           DATE
OOC_END_TM           DATE
OOC_REASON_TX        VARCHAR2(250 BYTE)
OOC_RESERVED_FOR     VARCHAR2(30 BYTE)
OOC_CLS_ID           NUMBER(9,0)
OOC_TIMEFRAME        VARCHAR2(1 BYTE)
OOC_WSD_CD           VARCHAR2(2 BYTE)
OOC_TEAM_UNIT_ID     NUMBER(6,0)
OOC_WSD_ACT_RMAT_ID  NUMBER(6,0)

TRAINERS table:

TRSC_ID                NUMBER(9,0) -- generated sequence
TRSC_OOC_UNIT_ID       NUMBER(6,0)
TRSC_OOC_START_DT      DATE
TRSC_OOC_START_TM      DATE
TRSC_OOC_RESERVED_FOR  VARCHAR2(30 BYTE)
TRSC_TPOC_ID           NUMBER(6,0)
TRSC_DT_CREATED        DATE
TRSC_USER_CREATED      VARCHAR2(30 BYTE)
TRSC_DT_MOD            DATE
TRSC_USER_MOD          VARCHAR2(30 BYTE)
TRSC_REMARKS           VARCHAR2(250 BYTE)
TRSC_NOSHOW_REASON     VARCHAR2(100 BYTE)

Tables should be joined on OOC_UNIT_ID=TRSC_OOC_UNIT_ID, OOC_START_DT=TRSC_OOC_START_DT and OOC_START_TM=TRSC_OOC_START_TM.

Primary Key for ROOMS table is: OOC_UNIT_ID, OOC_START_DT, OOC_START_TM. Primary Key for the TRAINERS table is: TRSC_ID.

I need to query this data by OOC_UNIT_ID, OOC_START_DT, OOC_START_TM, OOC_END_DT, OOC_END_TM and OOC_WSD_ACT_RMAT_ID.

In SQL it might be something like:

SELECT * 
  FROM TRAINERS t, ROOMS r
 WHERE t.TRSC_OOC_UNIT_ID = r.OOC_UNIT_ID
   AND t.TRSC_OOC_START_DT = r.OOC_START_DT
   AND t.TRSC_OOC_START_TM = r.OOC_START_TM
   AND ...

I am using the ROOMS table elsewhere in the project and it is already mapped as a standalone object. Would there be a way to utilize that as a sub-object on a TRAINERS object, or would it be easier to map these two tables into one flat object? How would the mapping look?

Thanks, Nick

A: 

In my experience simplicity is key when using any ORM including Hibernate. I would create a database view based on your SQL lets call that TRAINERS_ROOMS then simple map that database view to a new Java object lets call that TrainersRooms.

You get simple easy to manager hibernate mappings, but of course you can perform any updates using this new object so if you need that, this solution won't work out for you.

Tendayi Mawushe
+1  A: 

To map a single class to two (or more) separate tables you need to use a @SecondaryTable annotation:

@Table(name="ROOMS")
@SecondaryTable(name="TRAINERS", pkJoinColumns={
    @PrimaryKeyJoinColumn(name="TRSC_OOC_UNIT_ID", referencedColumnName="OOC_UNIT_ID"),
    @PrimaryKeyJoinColumn(name="TRSC_OOC_START_DT", referencedColumnName="OOC_START_DT"),
    @PrimaryKeyJoinColumn(name="TRSC_OOC_START_TM", referencedColumnName="OOC_START_TM")
})
public class MyMergedEntity {

You'll then need to annotate each individual property mapped to TRAINERS table with @Column(table="TRAINERS") to specify which table it belongs to. If you're using XML mappings instead, all of the above can be done via join element.

All that said, it seems to me that your two tables are rather different in nature and should not be mapped to a single class (especially since you've said you've already mapped ROOMS elsewhere). Perhaps you should map your Trainer as ManyToOne association instead.

ChssPly76
+1  A: 

Solution I've come up with seems to be working as far as querying data, I haven't tried any insert/update/delete yet.

I created the TRAINER object to extend the ROOM object.

public class Trainer extends Room {
  ...
}

Then I modified the mapping for ROOM to include a joined-subclass:

<hibernate-mapping>
   <class name="Room" table="ROOMS">
      <composite-id> ...
      <property ...>
      ...

      <joined-subclass name="Trainer" table="TRAINERS">
         <key>
              <column ...>
              ...
         </key>
         <property ...>
         ...
      </joined-subclass>
   </class>
 ...

So far it appears to be working.

Thanks,

Nick

Nicholas Smith
It seems **really** strange to implement this using inheritance as ROOMS and TRAINERS seem to be very different concepts. What is the relation between a Trainer and a Room? Is a Trainer a Room?
Pascal Thivent
This is horribly wrong. Insert / delete would affect both tables simultaneously plus you'll be doing joins to `TRAINERS` every time you try to use `Room` object. Room and Trainer have one-to-many (or many-to-many) association, they most certainly do not belong in a hierarchy.
ChssPly76
A: 

You can create a named query that is binded to a custom object. This is the solution I would go with, since no changes to the DB would be necessary.

monksy