エンティティー・リスナーおよびコールバック・メソッド

アプリケーションは、エンティティーの状態が遷移した場合に通知を受けることができます。状態変更イベントに対しては、2 つのコールバック・メカニズムが存在します。1 つはエンティティー・クラスに定義されているライフサイクル・コールバック・メソッドで、エンティティーの状態が変更されると必ず呼び出されます。もう 1 つはエンティティー・リスナーで、いくつかのエンティティーに登録できるのでより一般的になっています。

エンティティー・インスタンスのライフサイクル

エンティティー・インスタンスには、以下の状態があります。

エンティティーの状態が変化するときは、 ライフサイクル・コールバック・メソッドを起動できます。

以下のセクションでは、 新規、管理対象、切り離し済み、除去済み、および無効化の状態がエンティティーに適用されるときの 各状態の意味について詳細に説明します。

エンティティー・ライフサイクル・コールバック・メソッド

エンティティー・ライフサイクル・コールバック・メソッドは、エンティティー・クラスに定義でき、エンティティーの状態が変わると呼び出されます。こうしたメソッドは、エンティティー・フィールドの妥当性検査や、通常ではエンティティーで持続することのない過渡状態の更新で役立ちます。エンティティー・ライフサイクル・コールバック・メソッドは、エンティティーを使用していないクラスでも定義することができます。こうしたクラスは、複数のエンティティー・タイプに関連付けることができるエンティティー・リスナー・クラスです。ライフサイクル・コールバック・メソッドは、以下のようにメタデータ・アノテーションを使用しても、エンティティー・メタデータ XML 記述子ファイルを使用しても定義できます。

エンティティー・リスナー

エンティティー・リスナー・クラスは、エンティティーを使用しないクラスであり、1 つ以上のエンティティー・ライフサイクル・コールバック・メソッドを定義します。エンティティー・リスナーは、汎用の監査アプリケーションまたはロギング・アプリケーションで有用です。エンティティー・リスナーは、以下のようにメタデータ・アノテーションを使用しても、エンティティー・メタデータ XML 記述子ファイルを使用しても定義できます。

コールバック・メソッドの要件

アノテーションのどのようなサブセットまたは組み合わせでも、エンティティー・クラスまたはリスナー・クラスに指定できます。1 つのクラスは、同じライフサイクル・イベントに対する複数のライフサイクル・コールバック・メソッドを持つことができません。ただし、同じメソッドを複数のコールバック・イベントに使用することができます。エンティティー・リスナー・クラスには、引数を取らない public コンストラクターが必要です。エンティティー・リスナーはステートレスです。 エンティティー・リスナーのライフサイクルは、指定されません。 eXtreme Scale はエンティティー継承をサポートしないため、コールバック・メソッドは、エンティティー・クラスでしか定義できず、スーパークラスでは定義できません。

コールバック・メソッド・シグニチャー

エンティティー・ライフサイクル・コールバック・メソッドは、エンティティー・リスナー・クラスで定義するか、エンティティー・クラスで直接定義するか、あるいはその両方で定義できます。エンティティー・ライフサイクル・コールバック・メソッドは、メタデータ・アノテーションを使用しても、エンティティー XML 記述子を使用しても定義できます。 エンティティー・クラスとエンティティー・リスナー・クラスでコールバック・メソッドに使用されるアノテーションは、同じです。コールバック・メソッドのシグニチャーは、エンティティー・クラスで定義する場合と、エンティティー・リスナー・クラスで定義する場合とでは異なります。エンティティー・クラスまたはマップされたスーパークラスで定義されるコールバック・メソッドは、以下のシグニチャーを持ちます。
void <METHOD>()
エンティティー・リスナー・クラスで定義されるコールバック・メソッドは、以下のシグニチャーを持ちます。
void <METHOD>(Object)
Object 引数は、コールバック・メソッドの呼び出し対象のエンティティー・インスタンスです。 Object 引数は、java.lang.Object オブジェクトまたは実際のエンティティー・タイプとして宣言できます。

コールバック・メソッドには public、private、protected、または package レベルのアクセスが可能ですが、static または final は使用できません。

対応するタイプのライフサイクル・イベント・コールバック・メソッドを指定するために、以下のアノテーションが定義されます。
  • com.ibm.websphere.projector.annotations.PrePersist
  • com.ibm.websphere.projector.annotations.PostPersist
  • com.ibm.websphere.projector.annotations.PreRemove
  • com.ibm.websphere.projector.annotations.PostRemove
  • com.ibm.websphere.projector.annotations.PreUpdate
  • com.ibm.websphere.projector.annotations.PostUpdate
  • com.ibm.websphere.projector.annotations.PostLoad
詳しくは、API 資料を参照してください。各アノテーションには、エンティティー・メタデータ XML 記述子ファイルで定義された同等の XML 属性があります。

ライフサイクル・コールバック・メソッドのセマンティクス

以下のように、異なるライフサイクル・コールバック・メソッドは、それぞれ異なる目的を持ち、エンティティー・ライフサイクルの異なるフェーズで呼び出されます。
PrePersist
エンティティーに対して、そのエンティティーがストアに対して永続化される前に呼び出されます。こうしたエンティティーには、カスケード操作のために永続化されているエンティティーが含まれます。このメソッドは、EntityManager.persist 操作のスレッドで呼び出されます。
PostPersist
エンティティーに対して、そのエンティティーがストアに対して永続化された後に呼び出されます。こうしたエンティティーには、カスケード操作のために永続化されているエンティティーが含まれます。このメソッドは、EntityManager.persist 操作のスレッドで呼び出されます。これは、EntityManager.flush または EntityManager.commit が呼び出された後で呼び出されます。
PreRemove
エンティティーに対して、そのエンティティーが除去される前に呼び出されます。こうしたエンティティーには、カスケード操作のために除去されたエンティティーが含まれます。このメソッドは、EntityManager.remove 操作のスレッドで呼び出されます。
PostRemove
エンティティーに対して、そのエンティティーが除去された後に呼び出されます。こうしたエンティティーには、カスケード操作のために除去されたエンティティーが含まれます。このメソッドは、EntityManager.remove 操作のスレッドで呼び出されます。これは、EntityManager.flush または EntityManager.commit が呼び出された後で呼び出されます。
PreUpdate
エンティティーに対して、そのエンティティーがストアに対して更新される前に呼び出されます。このメソッドは、トランザクション・フラッシュ操作またはコミット操作のスレッドで呼び出されます。
PostUpdate
エンティティーに対して、そのエンティティーがストアに対して更新された後に呼び出されます。このメソッドは、トランザクション・フラッシュ操作またはコミット操作のスレッドで呼び出されます。
PostLoad
エンティティーに対して、そのエンティティーがストアからロードされた後に呼び出されます。こうしたエンティティーには、アソシエーションによってロードされたエンティティーが含まれます。このメソッドは、EntityManager.find や照会などのロード操作のスレッドで呼び出されます。

ライフサイクル・コールバック・メソッドの重複

エンティティー・ライフサイクル・イベントに対して複数のコールバック・メソッドが定義されている場合、これらのメソッドの呼び出し順序は以下のとおりです。
  1. エンティティー・リスナーで定義されたライフサイクル・コールバック・メソッド: エンティティー・クラスのエンティティー・リスナー・クラスで定義されたライフサイクル・コールバック・メソッドは、EntityListeners アノテーションまたは XML 記述子でエンティティー・リスナー・クラスが指定されているのと同じ順序で呼び出されます。
  2. リスナー・スーパー・クラス: エンティティー・リスナーのスーパー・クラスで定義されたコールバック・メソッドは、子の前に呼び出されます。
  3. エンティティー・ライフサイクル・メソッド: WebSphere® eXtreme Scale はエンティティー継承をサポートしないため、エンティティー・ライフサイクル・メソッドはエンティティー・クラス内でしか定義できません。

例外

ライフサイクル・コールバック・メソッドで実行時例外が発生する場合があります。ライフサイクル・コールバック・メソッドの結果としてトランザクション内で実行時例外が発生した場合、そのトランザクションがロールバックされます。実行時例外となった後は、それ以上ライフサイクル・コールバック・メソッドが呼び出されません。