Hitachi

Cosminexus V11 アプリケーションサーバ 機能解説 互換編


8.4.6 永続化コンテキストからのエンティティの切り離しとmerge操作

永続化コンテキストから切り離されたエンティティをdetached状態のエンティティといいます。エンティティは次のタイミングでdetached状態になります。

切り離されたエンティティのインスタンスは,永続化や取得をした永続化コンテキストの外で存在し続けます。エンティティの状態とデータベースの状態は同期されません。

〈この項の構成〉

(1) detached状態のエンティティへのアクセス

アプリケーションは永続化コンテキストの終了後でも,detached状態のエンティティにアクセスできます。この場合,エンティティのフィールドおよび関連先は,フェッチ済みである必要があります。detached状態のエンティティでフェッチされていないフィールドおよび関連先のエンティティにはアクセスできません。なお,フィールドに指定する@Basicには常にFetchType.EAGERが適用されるため,関連先のエンティティやフィールドの情報が取得済みとなります。

リレーションシップではdetached状態のエンティティからアクセスするには,次に示すどれかの条件を満たす必要があります。

利用できないインスタンスへのアクセス,および利用できるインスタンスの無効なステートへのアクセスを行った場合は,例外が発生します。ただし,CJPAプロバイダでは,FetchType.LAZYを指定した場合,EntityManagerの終了後にdetached状態になっていても,フェッチされていないフィールドおよび関連先エンティティにアクセスすると,データベースから値を取得して,内容を参照することができる場合があります。

(2) エンティティのmerge処理

EntityManagerのmergeメソッドの呼び出し,またはmerge処理のカスケードによって,detached状態のエンティティをEntityManagerで管理される永続化コンテキストにマージできます。

次の表にmerge処理でのエンティティの状態遷移を,エンティティAの状態ごとに示します。

表8‒15 merge処理でのエンティティの状態遷移の結果

エンティティAの状態

状態遷移の結果

new

managed状態のエンティティA'が新しく作成されて,エンティティAの状態がエンティティA'にコピーされます。mergeの引数のエンティティはnewのままであることに注意してください。

managed

merge操作は無視されます。しかし,エンティティAからほかのエンティティへのリレーションシップのcascade属性に,MERGEまたはALLが指定されている場合,エンティティAが参照するエンティティにmerge操作が伝播されます。

detached

エンティティAの状態が,同じIDを持つすでに存在している管理されたエンティティA'にコピーされます。または,エンティティAのコピーである新しいmanaged状態のエンティティが作成されます。mergeの引数のエンティティはdetached状態のままであることに注意してください。

removed

merge操作によって,IllegalArgumentExceptionが発生します。または,トランザクションのコミットに失敗します。エンティティAの状態はremoved状態のままであることに注意してください。

注1 エンティティAからエンティティBへのリレーションがcascade=MERGEまたはcascade=ALLで指定されていると,すべてのエンティティBは再帰的にエンティティB'としてマージされます。エンティティA'にはエンティティB'がセットされます。なお,エンティティAがmanaged状態の場合,エンティティAとエンティティA'は同じであることに注意してください。

注2 エンティティAのリレーションにcascade=MERGEまたはcascade=ALLが指定されていない状態でエンティティBを参照している場合,エンティティAがエンティティA'にマージされるときには,エンティティA'から関連をたどるとエンティティBと同じ永続化アイデンティティを持つ管理されたエンティティB'の参照にたどり着きます。

JPA仕様では,フェッチされていないことを意味するLAZYにマークされたフィールドはマージのときに無視されます。ただし,CJPAプロバイダでは,@BasicはEAGERとして動作するため,リレーションシップでないすべてのフィールドはマージ処理の対象となります。

また,Version列がエンティティで使われている場合は,マージ操作とそのあとに呼ばれるフラッシュおよびコミット処理時に,エンティティのバージョンチェックを実行します。Version列が存在しない場合,merge操作ではエンティティのバージョンチェックは実行されません。詳細については,「8.10.1 楽観的ロックの処理」を参照してください。

なお,CJPAプロバイダでは,ほかベンダとの間で,エンティティのマージ処理によって永続化コンテキストに戻すという処理はサポートしていません。

(3) 注意事項