EJB 3.0(Proposed Final Draft)入門記 Java Persistence API Chapter 9 その1

だんだん早く帰れるようになったし、引越しも終わったしでそろそろ気合を入れてかないとなぁ。いつの間にか正月でもないし。そういえば初詣行ってない。
今度の日曜で結構大きめのタスクが終わる(はず)のでそれが終わったらできるだけJava Persistence APIに力を注ぎ込む予定です。

Chapter 9 Metadata for Object/Relational Mapping

今日からChapter 9です。Proposed Final Draftの実装が出るまではドキュメントを読み進めようと思います。ADSLがまだつながらないので最近情報収集がうまくいってないですが、Proposed Final Draftの実装ってまだ出てないよね?

9.1 Annotations for Object/Relational Mapping

書いてあることを羅列すると

当然かもしれないですけどクエリもアプリもメタデータに依存するんですね。ということはO/Rマッピングメタデータがクエリやアプリに及ぼす影響は大きいわけで、メタデータをちゃんと知ることは超重要。とはいえ結構量があります。

あと、JPA実装によるDDL生成のサポートが認められているそうです。でもポータブルなアプリケーションはDDL生成を使うことを当てにしちゃ駄目だって。ここでのDDL生成ってたとえばHibernateだとhbm2ddlに相当するものだと思っていいのかな?

9.1.1 Table Annotation

では、Tableアノテーションから。TableアノテーションはエンティティにPrimary Tableを指定するために使います。このアノテーションを指定しない場合はEntityの名称がテーブル名となります。

@Target({TYPE}) @Retention(RUNTIME)
public @interface Table {
  String name() default "";
  String catalog() default "";
  String schema() default "";
  UniqueConstraint[] uniqueConstraints() default {};
}
9.1.2 SecondaryTable Annotation

ひとつのエンティティにひとつのテーブル(Primary Table)だけでなく2つ目のテーブル(Secondary Table)をマッピングしたいときにSecondaryTableを使います。

@Target({TYPE}) @Retention(RUNTIME)
public @interface SecondaryTable {
  String name();
  String catalog() default "";
  String schema() default "";
  PrimaryKeyJoinColumn[] pkJoinColumns() default {};
  UniqueConstraint[] uniqueConstraints() default {};
}

よくわからなかったのはPrimaryKeyJoinColumnです。こいつにはPrimary Tableのプライマリキーを参照するSecondary Tableのプライマリキーを指定するみたい。

たとえば、次のようなテーブル定義がある場合

CREATE TABLE CUSTOMER(
  ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1)  NOT NULL PRIMARY KEY,
  NAME VARCHAR(255)
)
CREATE TABLE CUST_DETAIL(
  CUST_ID INTEGER NOT NULL PRIMARY KEY,
  ADDRESS VARCHAR(255)
)
ALTER TABLE CUSTOMER_DETAIL ADD CONSTRAINT FK_CUSTOMER_ID FOREIGN KEY(CUST_ID) REFERENCES CUSTOMER(ID)

このようなアノテーションで表せるはず(たぶん)

追記
下記のコードですが@GeneratedValueと@Column(table="CUST_DETAIL")を追加しました。

@Entity
@Table(name="CUSTOMER")
@SecondaryTable(name="CUST_DETAIL",
pkJoinColumns=@PrimaryKeyJoinColumn(name="CUST_ID"))
public class Customer {
  @Id
  @GeneratedValue
  private int id;
  private String name;
  @Column(table="CUST_DETAIL")
  private String address;
}
9.1.3 SecondaryTables Annotation

SecondaryTableアノテーションの複数形SecondaryTableアノテーション。ひとつのエンティティに2つ以上のテーブルをマッピングするときに使うみたいです。

@Target({TYPE}) @Retention(RUNTIME)
public @interface SecondaryTables {
  SecondaryTable[] value();
}

複数のテーブルをひとつのエンティティにまとめるのとひとつのテーブルを細かいエンティティに分けるのとどっちが多いかなぁ。基本的にはテーブルとエンティティは1対1がわかりやすくていいと思います。