- PR -

Hibernateで複合キーを利用したリレーショナルなデータ獲得方法について

1
投稿者投稿内容
hiro
常連さん
会議室デビュー日: 2004/09/02
投稿数: 21
投稿日時: 2004-09-02 17:41
現在、Hibernateを利用したアプリケーションを開発していて
リレーショナルなデータアクセスを行う際に
・<many-to-one> 1対多
・<one-to-many> 多対1
などの定義を利用したいのですが、リファレンスなどには単一キーによる
データアクセスの例しかなく(推奨されていないため?)、
キーが複合である場合のアクセス方法が解らず立ち止まってしまいました。

どなたかこのような事象を検証された方がいれば、内容について教えてください。
以下は、データアクセス対象となっているスキーマの例です。

create table Person(
personid varchar(10) not null,
tourokudate date not null,
name varchar(32),
address varchar(128),
primary key (id,tourokudate)
)

create table Sagyou(
personid varchar(10) not null,
tourokudate date not null,
workcode varchar(128),
workdate date,
primary key (id,tourokudate,workcode,workdate)
)

上記のようなスキーマがあります。
Personは人の履歴を管理していて、Sagyouはその人が実施した作業を管理しています。
このような2つのスキーマでpersonid,tourokudateを外部キーとしたデータアクセスを行いたいのです。
どなたか解る方があればよろしくお願いします。

[ メッセージ編集済み 編集者: 未記入 編集日時 2004-09-02 18:21 ]
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2004-09-06 11:23
id要素の代わりに composite-id要素を使えばできます。ただ、複合キーの一部が複合キーを参照しているので、key-many-to-one 要素も必要です。大事なのははCompositeIDというpersonidとtourokudateを一緒にしたキークラスを作る事です。

詳しい内容は英語ですが、
5.1.5. composite-id
7.4. Components as composite identifiers
を読むと分かります。

下記のコードを参考にしてください。

コード:
<class name="Person" table="Persons">
  <composite-id name="id" class="CompositeID"> <!--複合キーを使う-->
    <key-property name="personid" />
    <key-property name="tourokudate" />
  </composite-id>
  <property name="mame" type="java.lang.String" />
  <property name="address" type="java.lang.String" />
</class>

<class name="Sagyo" table="Sagyo">
  <composite-id>
    <key-many-to-one name="id" class="Person">
      <column name="personid" />
      <column name="tourokudate" /> 
    </key-many-to-one>
    <key-property name="workcode" type="java.lang.String" />
    <key-property name="date" type="java.util.Calendar" />
  </composite-id>
</class>

public class CompositeID implements Serializable {
  private String personid;
  private Calendar tourokudate;
  //getterとsetter メソッド
  //equals と hashCode メソッドは必ずoverrideすること
}
public class Person implements Serializable {
  private CompositeID id;
  private String name;
  private String address;  
  //getterとsetter メソッド
  //equals と hashCode メソッドは必ずoverrideすること
}
public class Sagyo implements Serializable {
  private CompositeID id;
  private String workcode;
  private Calendar date;
  //getterとsetter メソッド
  //equals と hashCode メソッドは必ずoverrideすること
}




ちなみに、PostgreSQLを使った場合SchemaExportで以下のschemaができました。
コード:
create table Persons (
   personid VARCHAR(255) not null,
   tourokudate TIMESTAMP not null,
   mame VARCHAR(255),
   address VARCHAR(255),
   primary key (personid, tourokudate)
)
create table Sagyo (
   personid VARCHAR(255) not null,
   tourokudate TIMESTAMP not null,
   workcode VARCHAR(255) not null,
   date TIMESTAMP not null,
   primary key (personid, tourokudate, workcode, date)
)

alter table Sagyo add 
constraint FK4BF488F3079D31F foreign key (personid, tourokudate) 
references Persons



unkhown00
会議室デビュー日: 2005/08/16
投稿数: 1
投稿日時: 2005-08-16 12:34
リレーションというキーワードからは外れますが、複合キー絡みということで、こちらのスレッドに便乗させてください。

引用:

H2さんの書き込み (2004-09-06 11:23) より:
id要素の代わりに composite-id要素を使えばできます。ただ、複合キーの一部が複合キーを参照しているので、key-many-to-one 要素も必要です。大事なのははCompositeIDというpersonidとtourokudateを一緒にしたキークラスを作る事です。



例で出てくるPersonsテーブルに対して「personid='001'」のレコードをSelectしようと思ったらどのようなコーディングが必要になるのでしょうか?

複合キーを使っていないテーブルのSelectは簡単に出来たのですが、こちらはHibernateのドキュメントに例が見当たらず四苦八苦しております。出来ればHQL,Criteriaでの例も見てみたいです。
1

スキルアップ/キャリアアップ(JOB@IT)