第6章 エンティティリスナーおよびコールバックメソッド
6.1. 定義 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
多くの場合、アプリケーションが永続メカニズム内部で発生した特定のイベントに反応することは役に立ちます。これにより、特定の種類の汎用機能を実装したり、組み込み機能を拡張したりできるようになります。JPA 仕様は、このために 2 つの関連するメカニズムを提供します。
エンティティのメソッドは特定のエンティティライフサイクルイベントの通知を受け取るコールバックメソッドとして指定できます。コールバックメソッドは、コールバックアノテーションによりアノテートされます。また、エンティティクラス内部で直接定義されたコールバックメソッドの代わりに使用するエンティティリスナークラスを定義できます。エンティティリスナーは引数なしのコンストラクタを持つステートレスクラスです。エンティティリスナーは、
@EntityListeners アノテーションでエンティティクラスをアノテートすることにより定義されます。
@Entity
@EntityListeners(class=Audit.value)
public class Cat {
@Id private Integer id;
private String name;
private Date dateOfBirth;
@Transient private int age;
private Date lastUpdate;
//getters and setters
/**
* Set my transient property at load time based on a calculation,
* note that a native Hibernate formula mapping is better for this purpose.
*/
@PostLoad
public void calculateAge() {
Calendar birth = new GregorianCalendar();
birth.setTime(dateOfBirth);
Calendar now = new GregorianCalendar();
now.setTime( new Date() );
int adjust = 0;
if ( now.get(Calendar.DAY_OF_YEAR) - birth.get(Calendar.DAY_OF_YEAR) < 0) {
adjust = -1;
}
age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR) + adjust;
}
}
public class LastUpdateListener {
/**
* automatic property set before any database persistence
*/
@PreUpdate
@PrePersist
public void setLastUpdate(Cat o) {
o.setLastUpdate( new Date() );
}
}
同じコールバックメソッドまたはエンティティリスナーメソッドは複数のコールバックアノテーションでアノテートできます。該当するエンティティに対して、2 つのメソッドを同じコールバックアノテーションによりアノテートすることはできません (コールバックメソッドであるか、エンティティリスナーメソッドであるかは関係ありません)。コールバックメソッドは引数がないメソッド (戻り値タイプがなく任意の名前) です。エンティティリスナーはシグネチャ
void <METHOD>(Object) (Object は実際のエンティティタイプ) です (Hibernate Entity Manager ではこの制限が緩和され、java.lang.Object タイプの Object を使用できます (複数のエンティティでリスナーを共有できます)。
コールバックメソッドは
RuntimeException を発生させます。現在のトランザクション (存在する場合) はロールバックする必要があります。以下のコールバックが定義されます。
| タイプ | 定義 |
|---|---|
| @PrePersist | エンティティマネージャの永続化操作が実際に実行される、またはカスケードされる前に実行されます。このコールは永続化操作と同期されます。 |
| @PreRemove | エンティティマネージャの削除操作が実際に実行される、またはカスケードされる前に実行されます。このコールは削除操作と同期されます。 |
| @PostPersist | エンティティマネージャの永続化操作が実際に実行される、またはカスケードされる前に実行されます。このコールはデータベースの INSERT の実行後に行われます。 |
| @PostRemove | エンティティマネージャの削除操作が実際に実行される、またはカスケードされる前に実行されます。このコールはデータベースの削除操作と同期されます。 |
| @PreUpdate | データベースの UPDATE 操作が実行される前に実行されます。 |
| @PostUpdate | データベースの UPDATE 操作が実行された後に実行されます。 |
| @PostLoad | エンティティが現在の永続化コンテキストにロードされた後、またはエンティティ更新された後に実行されます。 |
コールバックメソッドは
EntityManager メソッドまたは Query メソッドを呼び出さないようにする必要があります。