4 エンティティの理解
エンティティは、軽量な永続性ドメイン・オブジェクトです。
一般的に、エンティティはリレーショナル・データベースの表を表現し、各エンティティ・インスタンスはその表の行に相当します。エンティティの主なプログラミング・アーティファクトはエンティティ・クラスですが、各エンティティはヘルパー・クラスを使用できます。
エンティティの永続状態は、永続フィールドまたは永続プロパティを通じて表現されます。これらのフィールドまたはプロパティでは、オブジェクト/リレーショナル・マッピングの注釈を使用して、エンティティおよびエンティティ関係を、基礎となるデータ・ストアのリレーショナル・データにマップします。
エンティティの識別
@Entity注釈を使用して、クラスがエンティティであることを指定します。
注意:
エンティティ・クラスは、<exclude-unlisted-classes>タグをfalseに設定しないかぎり、persistence.xmlファイルにもリストする必要があります。
詳細は、JPA仕様の第2章「Entities」を参照してください。
エンティティと永続識別子
すべてのエンティティは、エンティティ状態を格納するデータベース表の主キーに相当する永続識別子を持つ必要があります。
デフォルトで、EclipseLinkの永続性プロバイダは、主キーとして機能する1つ以上のフィールドまたはプロパティが各エンティティに含まれるものと想定します。
次の注釈を使用して、エンティティの識別子を生成または構成できます。
-
@Id
-
@IdClass
-
@EmbeddedId
-
@GeneratedValue
-
@TableGenerator
-
@SequenceGenerator
-
@UuidGenerator
これらの注釈を使用して、エンティティの識別子をデータベースで管理する方法を調整することもできます。これらの注釈の詳細は、JPA仕様の「Metadata for Object/Relational Mapping」を参照してください。
エンティティとデータベース表
すべてのエンティティ・クラスは、データベースの特定の表または表のセットにマップされます。
デフォルトで、エンティティの表名は大文字でそのエンティティ名に設定されます(これは、デフォルトでエンティティの短縮クラス名に設定されます)。エンティティは、通常、単一の表にマップされますが、複数の表やビューにもマップできます。
エンティティの表は、次の注釈を使用してカスタマイズできます。
-
@Table
-
@SecondaryTable
エンティティと継承
JPAは、継承でオブジェクトを永続化するための様々な方法を定義しています。
@Inheritance注釈は、SINGLE_TABLE、JOINEDおよびTABLE_PER_CLASSの継承を定義するためにルート・クラスで使用します。一般的な状態または永続性の動作を定義するが、データベース上に関係が存在しない抽象クラスでは、@MappedSuperclass注釈を使用できます。
-
@Inheritance
-
@MappedSuperclass
エンティティと埋込みオブジェクト
埋込み可能クラスは、直接永続化されず、親エンティティでのみ永続化される特別なタイプのクラスです。
@Embeddable注釈を使用して埋込みクラスをマップできます。埋込み可能クラスは、単一の参照の場合には@Embedded注釈を、埋込みIDの場合には@EmbeddedIdを、CollectionまたはMap参照の場合には@ElementCollection注釈を使用して、エンティティまたは別の埋込み可能クラスから参照できます。埋込み可能クラスは、@MapKeyClass注釈を使用して任意のMapキーで使用することもできます。
-
@Embeddable
-
@EmbeddedId
-
@Embedded
-
@ElementCollection
エンティティと順序生成
多くのデータベースでは、順序と呼ばれるID生成の内部メカニズムがサポートされます。
基礎となるデータベースがサポートしている場合、データベースの順序を使用して識別子を生成できます。
-
@SequenceGenerator: @GeneratedValue注釈を使用してSEQUENCEタイプの主キー・ジェネレータを指定する場合、@SequenceGenerator注釈を使用してこの主キー・ジェネレータを調整し、次のことを実行できます。
-
アプリケーション要件またはデータベースのパフォーマンス・パラメータに一致するように、割当てサイズを変更できます。
-
既存のデータ・モデルに一致するように、初期値を変更できます(たとえば、主キーの値の範囲がすでに割当て済または予約済である既存のデータ・セットに基づいて作成する場合)。
-
既存のデータ・モデルで事前定義されている順序を使用できます。
-
-
@TableGenerator: @GeneratedValue注釈を使用してTABLEタイプの主キー・ジェネレータを指定する場合、@TableGenerator注釈を使用してこの主キー・ジェネレータを調整し、次のことを実行できます。
-
主キー・ジェネレータの表の名前が不適切な場合、予約語の場合、既存のデータ・モデルと互換性がない場合、またはデータベースの表名として無効な場合、その名前を変更できます。
-
アプリケーション要件またはデータベースのパフォーマンス・パラメータに一致するように、割当てサイズを変更できます。
-
既存のデータ・モデルに一致するように、初期値を変更できます(たとえば、主キーの値の範囲がすでに割当て済または予約済である既存のデータ・セットに基づいて作成する場合)。
-
特定のカタログまたはスキーマで主キー・ジェネレータの表を構成できます。
-
主キー・ジェネレータの表に含まれる1つ以上の列に対して一意制約を構成できます。
-
これらの注釈の詳細および例は、JPA仕様の「Metadata for Object/Relational Mapping」を参照してください。
エンティティとロック
デフォルトで、EclipseLinkの永続性プロバイダでは、アプリケーションがデータ整合性を管理するものと想定されます。
オプティミスティック・ロックとペシミスティック・ロックを選択できます。オプティミスティック・ロックの使用をお薦めします。詳細は、「ディスクリプタとロック」を参照してください。
@Version注釈を使用して、オプティミスティック・ロックの値として機能するエンティティ・クラスのバージョン・フィールドまたはプロパティを指定することで、JPA管理のオプティミスティック・ロックを有効化することをお薦めします。バージョン・フィールドまたはプロパティを選択する場合、次の条件を満たす必要があります。
-
1つのエンティティに対してただ1つのバージョン・フィールドまたはプロパティがあること
-
プライマリ表に永続化されているプロパティまたはフィールドを選択すること(JPA仕様の「Table Annotation」を参照)
-
アプリケーションでバージョン・プロパティまたはフィールドを変更しないこと
注意:
フィールドまたはプロパティ・タイプは、数値型(Number、long、int、BigDecimalなど)またはjava.sql.Timestampである必要があります。数値型の使用をお薦めします。
@Version注釈には属性はありません。
詳細は、次を参照してください。
-
JPA仕様(http://jcp.org/en/jsr/detail?id=338)の「Optimistic Locking and Concurrency」
-
JPA仕様(http://jcp.org/en/jsr/detail?id=338)の「Version Annotation」
-
『Java Persistence API (JPA) Extensions Reference for EclipseLink』のオプティミスティック・ロックのEclipseLink JPA拡張機能の説明
JPAメタデータによって構成されるEclipseLinkアーティファクトの詳細は、「ディスクリプタとロック」を参照してください。
拡張可能なエンティティ
JPAエンティティおよびJAXB Beanは、外部でマッピングを追加または変更して、拡張可能にすることができます。
エンティティまたはBeanのソース・ファイルの変更やBeanの永続性ユニットの再デプロイは必要ありません。
拡張可能なエンティティは、複数のクライアント(テナント)が共有の汎用アプリケーションを使用できるマルチテナント(またはSaaS)・アーキテクチャで役立ちます。テナントは、自分のデータにプライベートにアクセスでき、他のテナントと共有するデータにもアクセスできます。
拡張可能なエンティティを使用すれば、次のことを行えます。
-
一部のマッピングがすべてのユーザーに共通で、一部のマッピングはユーザー固有であるようなアプリケーションを作成できます。
-
顧客に提供された後のアプリケーションにマッピングを追加できます(デプロイメント後でも可能)。
-
マッピング変更後も、同じEntityManagerFactoryインタフェースを使用してデータを操作できます。
-
アプリケーションで使用されるメタデータのソースを追加提供できます。
@VirtualAccessMethods注釈を使用してJPAエンティティを拡張可能に指定し、@XmlVirtualAccessMethods注釈を使用してJAXB Beanを拡張可能に指定します。いずれの場合も、仮想プロパティを使用して外部でマッピングを指定します。これにより、ソース・ファイルの変更および永続性ユニットの再デプロイをしなくても、マッピングを変更できるようになります。
JPAエンティティおよびJAXB Beanを拡張可能にする方法の詳細は、『Solutions Guide for EclipseLink』の「Making JPA Entities and JAXB Beans Extensible」を参照してください。