Hibernate将两个表映射到一个类

时间:2009-11-03 15:09:14

标签: java sql oracle hibernate java-ee

我需要将两个表映射到一个类,无法解决这个问题。一张桌子是ROOMS,另一张桌子是TRAINERS。

ROOMS表:

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表:

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)

表格应加在OOC_UNIT_ID=TRSC_OOC_UNIT_IDOOC_START_DT=TRSC_OOC_START_DTOOC_START_TM=TRSC_OOC_START_TM上。

ROOMS表的主键是:OOC_UNIT_ID, OOC_START_DT, OOC_START_TM。 TRAINERS表的主键是:TRSC_ID

我需要按OOC_UNIT_IDOOC_START_DTOOC_START_TMOOC_END_DTOOC_END_TMOOC_WSD_ACT_RMAT_ID查询此数据。

在SQL中它可能类似于:

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 ...

我在项目的其他地方使用ROOMS表,它已被映射为独立对象。是否有办法将其用作TRAINERS对象上的子对象,或者将这两个表映射到一个平面对象会更容易吗?映射将如何显示?

谢谢, 尼克

4 个答案:

答案 0 :(得分:6)

要将单个类映射到两个(或更多)单独的表,您需要使用@SecondaryTable注释:

@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 {

然后,您需要使用TRAINERS注释映射到@Column(table="TRAINERS")表的每个单独属性,以指定它所属的表。如果您正在使用XML映射,则可以通过join元素完成上述所有操作。

所有这一切,在我看来,你的两个表在本质上是相当不同的,不应该映射到一个类(特别是因为你已经说过你已经在其他地方映射ROOMS)。也许您应该将您的培训师映射为ManyToOne关联。

答案 1 :(得分:1)

我提出的解决方案似乎正在查询数据,我还没有尝试过任何插入/更新/删除。

我创建了TRAINER对象来扩展ROOM对象。

public class Trainer extends Room {
  ...
}

然后我修改了ROOM的映射以包含一个连接子类:

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

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

到目前为止它似乎正在发挥作用。

谢谢,

尼克

答案 2 :(得分:0)

根据我的经验,简单是使用包括Hibernate在内的任何ORM时的关键。我将根据您的SQL创建一个数据库视图,调用TRAINERS_ROOMS然后简单地将数据库视图映射到新的Java对象,然后调用TrainersRooms

您可以轻松管理hibernate映射,但当然您可以使用这个新对象执行任何更新,因此如果您需要,此解决方案将无法为您解决。

答案 3 :(得分:0)

您可以创建绑定到自定义对象的命名查询。这是我要使用的解决方案,因为不需要对DB进行任何更改。