Entity Callbacks and Listeners (Enterprise JavaBeans 3.1)

 

When you execute EntityManager methods such as persist(), merge(), remove(), and find(), or when you execute JPA QL queries or use the Criteria API, a predefined set of lifecycle events are triggered. For instance, the persist() method triggers database inserts. Merging triggers updates to the database. The remove() method triggers database deletes. Querying entities triggers a load from the database. Sometimes it is very useful to have your entity bean class be notified as these events happen. For instance, maybe you want to create an audit log of every interaction done on each row in your database. The Java Persistence specification allows you to set up callback methods on your entity classes so that your entity instances are notified when these events occur. You can also register separate listener classes that can intercept these same events. These are called entity listeners. This topic discusses how you register your entity bean classes for lifecycle callbacks as well as how to write entity listeners that can intercept lifecycle events on your entities.

Callback Events

An annotation may represent each phase of an entity’s lifecycle:

tmp97160_thumb_thumb

The @PrePersist and @PostPersist events have to do with the insertion of an entity instance into the database. The @PrePersist event occurs immediately when the EntityManager.persist() call is invoked or whenever an entity instance is scheduled to be inserted into the database (as with a cascaded merge). The @PostPersist event is not triggered until the actual database insert.

The @PreUpdate event is triggered just before the state of the entity is synchronized with the database, and the @PostUpdate event happens after. This synchronization could occur at transaction commit time, when EntityManager.flush() is executed, or whenever the persistence context deems it necessary to update the database.

The @PreRemove and @PostRemove events have to do with the removal of an entity bean from the database. @PreRemove is triggered whenever EntityManager.remove() is invoked on the entity bean, directly or because of a cascade. The @PostRemove event happens immediately after the actual database delete occurs.

The @PostLoad event is triggered after an entity instance has been loaded by a find() or getReference() method call on the EntityManager interface, or when a JPA QL or Criteria query is executed. It is also called after the refresh() method is invoked.


Callbacks on Entity Classes

You can have an entity bean instance register for a callback on any of these lifecycle events by annotating a public, private, protected, or package-protected method on the bean class. This method must return void, throw no checked exceptions, and have no arguments:

tmp97161_thumb_thumb

}

When an event is triggered on a particular managed entity instance, the entity manager will invoke the appropriate annotated method on the entity bean class.

Entity Listeners

Entity listeners are classes that can generically intercept entity callback events. They are not entity classes themselves, but they can be attached to an entity class through a binding annotation or XML. You can assign methods on an entity listener class to intercept a particular lifecycle event. These methods return void and take one Object parameter that is the entity instance on which the event is being triggered. The method is annotated with the callback in which it is interested:

tmp97162_thumb_thumb

The entity listener class must have a public no-arg constructor. It can be applied to an entity class by using the @javax.persistence.EntityListeners annotation:

tmp97163_thumb_thumb

You may specify one or more entity listeners that intercept the callback events of an entity class:

tmp97164_thumb_thumb

By using the @EntityListeners annotation on the EntityListenerEmployee entity class, any callback methods within those entity listener classes will be invoked whenever EntityListenerEmployee entity instances interact with a persistence context.

Default Entity Listeners

You can specify a set of default entity listeners that are applied to every entity class in the persistence unit by using the <entity-listeners> element under the top-level <entity-mappings> element in the ORM mapping file. For instance, if you wanted to apply the Auditor listener to every entity class in a particular persistence unit, you would do the following:

tmp97165_thumb_thumb

If you want to turn off default entity listeners to a particular entity class, you can use the @javax.persistence.ExcludeDefaultListeners annotation:

tmp97166_thumb_thumb

If either the @ExcludeDefaultListeners annotation or its XML equivalent is applied to the EntityListenerEmployee entity, the Auditor is turned off for that entity.

Inheritance and Listeners

If you have an inheritance entity hierarchy in which the base class has entity listeners applied to it, any subclass will inherit these entity listeners. If the subclass also has entity listeners applied to it, then both the base and the subclass’s listeners will be attached:

tmp97167_thumb_thumb

In this example, the Auditor entity listener and AnotherListener will be attached to the DoubleEntityListenerEmployee entity. If all of these listeners have an @PostPersist callback, the order of callback execution will be as follows:

1. Auditor’s @PostPersist method

2. AnotherListener’s @PostPersist method

Entity listeners applied to a base class happen before any listeners attached to a subclass. Callback methods defined directly in an entity class happen last.

You can turn off inherited entity listeners by using @javax.persistence.ExcludeSuper classListeners:

tmp97168_thumb_thumb

In this example, no listeners would be executed for NoEntityListenerEmployee entity instances. @ExcludeSuperclassListeners has an XML equivalent in the <exclude-super class-listeners/> element.

 

Next post:

Previous post: