Cosminexus V9 アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)

[目次][用語][索引][前へ][次へ]

6.12.6 エンティティでのプライマリキーの指定

エンティティでは,プライマリキーをクラス階層の中で必ず指定してください。プライマリキーを指定する場合には,次に示すルールに従ってください。

これらの条件に従っていない場合は,アプリケーション開始時に例外が発生します。

また,アプリケーションでエンティティのプライマリキーの値を変更しないでください。アプリケーションでプライマリキーの値を変更した場合,実行時に例外が発生します。

<この項の構成>
(1) プライマリキーの型
(2) 複合型のプライマリキー
(3) 埋め込み型クラス

(1) プライマリキーの型

単体または複合型のプライマリキーは,次に示す型のどれかにしてください。

なお,近似値型(例えば浮動小数点数型)をプライマリキーとして指定すると,CJPAプロバイダの場合,丸め誤差が発生したり,equalsメソッドの結果に信頼性がないという問題が発生したりします。このため,CJPAプロバイダではプライマリキーに近似値型を使用した場合の動作は保証しません。java.util.Dateがプライマリキーとしてフィールド/プロパティで使用される場合,temporal type属性はDATE型として指定する必要があります。

(2) 複合型のプライマリキー

エンティティでは複合型のプライマリキーを扱うことができます。エンティティで複合型のプライマリキーを指定するには,埋め込み型クラスを利用する方法と@IdClassを利用する方法の2とおりがあります。それぞれの方法を説明します。

(a) 埋め込み型クラスを利用する方法

埋め込み型クラスを利用するには,@Embeddableを付与したクラスを作成し,そのクラスのフィールドとして複合型のプライマリキーを定義します。エンティティクラスでは,@Embeddableを付与したクラスの型のフィールドを定義して,@EmbeddedIdをアノテートします。エンティティクラスの例と埋め込み型クラスの例を次に示します。

埋め込み型クラスについては「(3) 埋め込み型クラス」を参照してください。なお,アノテーションの代わりにO/Rマッピングファイルを利用することもできます。

(b) @IdClassを利用する方法

@IdClassを利用するには,エンティティクラスでプライマリキーに対応する複数のインスタンス変数を定義して@Idを付与します。また,@IdClassを使用してプライマリキークラスを指定します。プライマリキークラスでは,エンティティで定義したプライマリキーと同じ名前と型を持つフィールドまたはプロパティを定義します。エンティティクラスの例とプライマリキークラスの例を次に示します。

埋め込み型クラスの場合と同様に,アノテーションの代わりにO/Rマッピングファイルを利用することもできます。なお,プライマリキークラスのアクセスタイプは,プライマリキーに対応するエンティティクラスのアクセスタイプで決定します。

複合型のプライマリキーを扱うためには,埋め込み型クラスまたは@IdClassのどちらかを使用します。ただし,次に示すルールに従ってください。

CJPAプロバイダでは,これらの条件を満たさない場合動作は保証しません。また,条件を満たさない場合はアプリケーションの開始時に例外が発生することもあります。

(3) 埋め込み型クラス

永続化対象の幾つかのフィールドをまとめたクラスを用意すると,エンティティのフィールドとして保持できます。このようなクラスを埋め込み型クラスといいます。

埋め込み型クラスは,エンティティに埋め込まれてエンティティと同じデータベースのテーブルにマップされます。このため,エンティティとは異なり,プライマリキーを持ちません。

ユーザが埋め込み型クラスを利用する場合,埋め込むクラスには@Embeddableを設定します。また,埋め込まれる側のエンティティクラスでは,埋め込み先のフィールド,プロパティに@Embeddedを指定します。なお,アノテーションの代わりにO/Rマッピングファイルで同様に定義することもできます。

埋め込み型クラスは複合型のプライマリキーを定義するために利用することもできます。この場合,埋め込まれるエンティティクラスでは,@Embeddedの代わりに@EmbeddedIdを設定します。

埋め込み型クラスでは,次に示す作成要件を必ず守ってください。

  1. 埋め込み型クラスは,必ず@Embeddableで定義するか,O/Rマッピングファイルの<embeddable>タグで定義してください。
  2. enumやインタフェースを埋め込み型クラスとしないでください。
  3. 埋め込み型クラスを含むエンティティクラスをdetachedオブジェクトとして値渡ししている場合,Serializableインタフェースを実装してください。
  4. 埋め込み型クラスおよび埋め込み型クラスの永続化インスタンス変数と,すべてのメソッドではfinalにしないでください。
  5. 引数なしのコンストラクタを持つ必要があります。
  6. 引数なしコンストラクタは,publicかprotectedで宣言してください。
  7. 埋め込み型クラスのインスタンス変数は,private,protected,またはpackageから参照できなければなりません。
  8. 埋め込み型クラスの永続化インスタンス変数は,クライアントから直接アクセスされないようにしてください。エンティティのアクセサメソッド(getter/setterメソッド)や,ほかのビジネスメソッドでアクセスしないでください。

CJPAプロバイダでは,1.および2.の条件を満たさない場合には例外が発生して,アプリケーションの開始に失敗します。また,3.から8.についても例外が発生するおそれがありますが,例外が発生しない場合でも動作は保証しません。

埋め込み型クラスのアクセスタイプは,埋め込まれた側のエンティティクラスのアクセスタイプで決定します。

埋め込み型クラスを利用する場合,埋め込みの階層は一つにしてください。また,複数のエンティティから埋め込み型クラスのオブジェクトを共有することはできません。これらの条件を満たさない場合,CJPAプロバイダでは動作を保証しません。