Cosminexus V9 アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)
トランザクションのコミットまたはflushメソッドの実行時に,エンティティの状態がデータベースに書き込まれます。一方,明示的にrefreshを呼び出さないかぎり,メモリにロードされたエンティティの状態のリフレッシュは実行されません。
ここでは,データベースへのエンティティ情報の書き込みと,データベースからのエンティティ情報の読み込みについて説明します。
flush操作またはトランザクションのコミットでのエンティティの状態遷移について説明します。次の表ではエンティティAの状態ごとに状態遷移の結果を示しています。
表6-11 flush操作またはトランザクションのコミットでのエンティティインスタンスの状態遷移
エンティティAの状態 | 状態遷移の結果 |
---|---|
new | flush操作は無視されます。 |
managed | データベースと同期されます。 |
removed | エンティティAはデータベースから削除されます。 |
detached | flush操作は無視されます。 |
また,managed状態のエンティティAがエンティティBに対してリレーションシップを持っている場合,flush処理の延長で次の表に示す条件に従って,persist操作がカスケードされます。
表6-12 関連するエンティティBへのflush処理およびコミットでのpersist操作のカスケード
エンティティBへのリレーションシップのcascade属性の指定 | エンティティBの状態 | 結果 |
---|---|---|
PERSISTまたはALLが指定されている | − | persist操作がエンティティBにカスケードされます。 |
PERSISTまたはALLが指定されていない | new |
|
managed | データベースと同期化されます。 | |
removed |
|
|
detached |
|
(凡例)−:該当しない
なお,トランザクションの外でflushメソッドを呼び出すと,TransactionRequiredExceptionが発生します。
EntityManagerのrefreshメソッドを呼び出すと,それまでに行われたエンティティの変更は破棄され,データベースの内容でエンティティの状態を上書きします。このとき,データベース上に対応する行が存在しない場合はEntityNotFoundExceptionが発生します。
エンティティがmanaged状態以外の場合に,EntityManagerのrefreshメソッドを呼び出すとIllegalArgumentExceptionが発生します。
refreshメソッドもしくはfindメソッドの実行時,またはクエリの発行時に,データベースからエンティティが読み込まれます。このときに,関連するエンティティもあわせて読み込むことができます。これをフェッチ戦略といいます。フェッチ戦略は各リレーションシップのfetch属性で指定します。fetch属性には次の2種類のどちらかを指定します。
FetchType.EAGERを指定するとデータベースからエンティティの情報を読み込むたびに,関連するフィールドやエンティティの情報を読み込みます。このため,不要な関連先のエンティティの取得を回避したい場合は,FetchType.LAZYを指定してください。
CJPAプロバイダでのfetch属性のサポート範囲を次の表に示します。
表6-13 リレーションシップごとのfetch属性のサポート範囲
リレーションシップのアノテーション | サポート範囲 |
---|---|
@ManyToMany | デフォルトはFetchType.LAZYです。 |
@OneToMany | デフォルトはFetchType.LAZYです。 |
@OneToOne | デフォルトはFetchType.EAGERです。なお,LAZYを指定したときには,(b)を参照してください。 |
@ManyToOne | デフォルトではFetchType.EAGERです。なお,LAZYを指定したときには,(b)を参照してください。 |
@Basic | fetch属性は無視されます。デフォルトのFetchType.EAGERが常に適用されます。 |
@OneToOneおよび@ManyToOneのリレーションシップに対してフェッチ戦略にLAZYを指定した場合,エンティティクラスのローディング時に,LAZYを指定したフィールドのgetterメソッドにバイナリコードを埋め込みます。
getterメソッドが呼び出されると,埋め込んだバイナリコードの処理を通して,データベースから関連先のエンティティを取得します。getterメソッドがバイナリの埋め込み対象になるため,リレーションの対象となるフィールドにアクセスするためのgetterメソッドを設定しておく必要があります。また,そのgetterメソッドに@OneToOneまたは@ManyToOneを設定しておく必要があります。
All Rights Reserved. Copyright (C) 2012, 2015, Hitachi, Ltd.