8.13.2 継承マッピング戦略
エンティティを継承した場合,クラス階層をテーブルにマッピングする方法を継承マッピング戦略として指定できます。継承マッピング戦略は,@InheritanceまたはO/Rマッピングファイルの<entity>タグの<inheritance>タグを使用して指定します。
継承マッピング戦略には次の3種類があります。
-
SINGLE TABLE戦略
SINGLE TABLE戦略は,エンティティクラスの継承階層にあるすべてのクラスが一つのテーブルにマップする戦略方法です。
-
JOINED戦略
JOINED戦略は,クラス階層の最上位は単一のテーブルにマップする戦略方法です。
-
TABLE PER CLASS戦略
エンティティクラスのクラス階層中の各クラスを別々のテーブルにマップする戦略方法です。
ただし,CJPAプロバイダでは,TABLE PER CLASS戦略は使用できません。CJPAプロバイダを使用している場合で,TABLE PER CLASS戦略を指定したときには,アプリケーションの起動時に例外が発生します。
- 注意事項
-
CJPAプロバイダを使用する場合,次のことに注意してください。
-
クラス階層中で継承戦略を複数組み合わせて指定することはできません。また,複数の継承戦略を組み合わせているかどうかのチェックも実施しません。指定した場合の動作は保証しません。
-
@DiscriminatorColumnで指定したカラムをエンティティのフィールドに定義した場合,persist操作をしてコミットしてもエンティティのフィールドに設定した値はデータベースに反映されません。@DiscriminatorValueで指定した値またはそのデフォルト値が反映されます。また,コミット後には,コミット前にフィールドに設定されていた値が格納されたままとなるため注意が必要です。
-
これらはjavax.persistence.DiscriminatorType列挙型の値で指定されます。それぞれの戦略について説明します。
- 〈この項の構成〉
(1) SINGLE TABLE戦略
SINGLE TABLE戦略とは,エンティティクラスの継承階層にあるすべてのクラスが一つのテーブルにマップする戦略方法です。そのため,テーブルではクラスを識別するためのカラムとして,識別カラムを持つ必要があります。
識別カラムは@DiscriminatorColumn,またはO/Rマッピングファイルで指定します。なお,デフォルトの識別カラム名は「DTYPE」です。データベースに識別カラムがない場合,アプリケーションの実行時に例外が発生します。
識別カラムに格納される値を指定したい場合には,@DiscriminatorValueまたはO/Rマッピングファイルの<entity>タグ下の<discriminator-value>タグを使用して指定します。
- 注意事項
-
SINGLE TABLE戦略を利用する場合,サブクラスのフィールドに対応するテーブルのカラムでは,null値を指定できるようにする必要があります。
(2) JOINED戦略
JOINED戦略とは,クラス階層の最上位は単一のテーブルにマップする戦略方法です。各サブクラスは,スーパークラスから継承されていないサブクラス特有のフィールドと,スーパークラス表の主キーの外部キーとして機能する主キー列を持つ別々のテーブルで示されます。
JOINED戦略の場合も,SINGLE TABLEの場合と同様にスーパークラスがマップされるテーブルに識別カラムを持つ必要があります。
- 注意事項
-
JOINED戦略を利用する場合,サブクラスのインスタンスの生成で複数回の結合の実行が必要になります。このため,階層構造が深くなると,性能が劣化するおそれがあります。また,クラス階層にわたる範囲でクエリを発行する場合,JOINが必要です。