EJB 3.0(Public Draft)入門記 Java Persistence API Chapter3 その5

今日はdetachedなエンティティとmergeがお題。


3.2.4 Detached Entities

persistence contextが終了すると、contextに関連づいているすべての管理された(managed)エンティティのインスタンスは切り離され(detached)るんだそうです。

persistence contextはいつ終了するんだ?と疑問がわきますが、デフォルトではトランザクション終了時だということが3.3に書いてありました。

persistence context終了後に、アプリケーションは有効な切り離されたエンティティの有効なステートに安全にアクセスできるらしいです。有効なステートとは次のものです。

  • fetch=LAZYと指定されていない永続フィールドやプロパティ
  • アプリケーションによってアクセスされている永続フィールドやプロパティ

もし永続フィールドやプロパティが関連ならば、関連インスタンスが有効な場合にのみ関連インスタンスのステートに安全にアクセスできるらしいです。有効なインスタンスとは次のものです。

  • find()を使って取得されたエンティティ
  • クエリを使って取得されたエンティティもしくはFETCH JOIN節で明示的に要求されたエンティティ
  • プライマリキーでない永続ステートをもったインスタンス変数がアプリケーションからアクセスされたエンティティ
  • fetch=EAGERと指定された関連をたどって別の有効なエンティティから取得されたエンティティ

3番目は意味はなんとなくわかるけど(訳はいまいちだけど)、理由がわからない。プライマリキーにアクセスしても有効なエンティティにならないのか。


「有効な」と考えるといろいろあるみたいだけど、逆に有効でないのは「遅延ローディングされるような値へのアクセス」ということだと思います。


3.2.4.1 Merging Detached Entity State

merge操作は切り離された(detached)エンティティのステートを永続(persistent)エンティティに伝達するそうです。切り離されたものが単に管理されたものになるのだけかと思っていたのですがどうやらそうではないみたい?ステートの伝達なんですね。


エンティティXに適用されるmerge操作のセマンティクスは次のとおりです。

  • Xが切り離された(detached)エンティティならば、Xは同じアイデンティティをもつすでに存在している管理されたエンティティX'にコピーされる、もしくはXのコピーである新しい管理されたエンティティが作成される。
  • Xが新しく(new)生成されたエンティティのインスタンスならば、新しい管理されたエンティティX'が生成され、XのステートがX'にコピーされる。
  • Xが削除された(removed)エンティティのインスタンスならば、IllegalArgumentExceptionがおきる。トランザクションが失敗する。
  • Xが管理された(managed)エンティティならば、merge操作は無視される。しかし、Xのリレーションシップがcascade=MERGEもしくはcascade=ALLでアノテートされていれば、merge操作はリレーションにカスケードする。
  • XからYへのリレーションがcascade=MERGEもしくはcascade=ALLでアノテートされていれば、すべてのYは再帰的にY'としてマージされる。X'にはY'がセットされる。
  • Xがcascade=MERGEもしくはcascade=ALLの指定なしでYを参照していて、そのXがX'にマージされるエンティティならば、X'から関連をたどるとYと同じ永続アイデンティティをもつ管理されたY'の参照に行き着く。

わかったようなわからないような。5番目と6番目は結果は同じ?