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マッピングのメタデータはアプリケーションドメインの規約の一部。
- アプリケーションドメインモデルに対応するデータベーススキーマに向けて書かれるクエリはO/Rマッピングのメタデータで表されるマッピングに依存する。
- JPA(Java Persistence API)の実装は、アプリケーションがO/Rマッピングのメタデータに依存することを想定しマッピングによって表されるセマンティクスと要件が守られることを保障しなければいけない。
当然かもしれないですけどクエリもアプリもメタデータに依存するんですね。ということは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がわかりやすくていいと思います。