841 words

JPA Lifecycle Events

Callback methods are user defined methods that are attached to entity lifecycle events and are invoked automatically by JPA when these events occur.

Internal Callback Methods

Internal callback methods are methods that are defined within an entity class. For example, the following entity class defines all the supported callback methods with empty implementations:

Internal callback methods should always return void and take no arguments. They can have any name and any access level (public, protected, package and private) but should not be static.

The annotation specifies when the callback method is invoked:

An entity class may include callback methods for any subset or combination of lifecycle events but no more than one callback method for the same event. However, the same method may be used for multiple callback events by marking it with more than one annotation.

By default, a callback method in a super entity class is also invoked for entity objects of the subclasses unless that callback method is overridden by the subclass.

Implementation Restrictions

To avoid conflicts with the original database operation that fires the entity lifecycle event (which is still in progress) callback methods should not call EntityMan­agerjavax.persistence.EntityManagerJPA interfaceInterface used to interact with the persistence context.
See JavaDoc Reference Page...
or Queryjavax.persistence.QueryJPA interfaceInterface used to control query execution.
See JavaDoc Reference Page...
methods and should not access any other entity objects.

If a callback method throws an exception within an active transaction, the transaction is marked for rollback and no more callback methods are invoked for that operation.

Listeners and External Callback Methods

External callback methods are defined outside entity classes in a special listener class:

External callback methods (in a listener class) should always return void and take one argument that specifies the entity which is the source of the lifecycle event. The argument can have any type that matches the actual value (e.g. in the code above, Object can be replaced by a more specific type). The listener class should be stateless and should have a public no-arg constructor (or no constructor at all) to enable automatic instantiation.

The listener class is attached to the entity class using the @EntityListenersjavax.persistence.EntityListenersJPA annotationSpecifies the callback listener classes to be used for an entity or mapped superclass.
See JavaDoc Reference Page...
annotation:

Multiple listener classes can also be attached to one entity class:

Listeners that are attached to an entity class are inherited by its subclasses unless the subclass excludes inheritance explicitly using the @ExcludeSuperclassListenersjavax.persistence.ExcludeSuperclassListenersJPA annotationSpecifies that the invocation of superclass listeners is to be excluded for the entity class (or mapped superclass) and its subclasses.
See JavaDoc Reference Page...
annotation:

Default Entity Listeners

Default entity listeners are listeners that should be applied by default to all the entity classes. Currently, default listeners can only be specified in a mapping XML file because there is no equivalent annotation:

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
  <persistence-unit-metadata>
    <persistence-unit-defaults>
      <entity-listeners>
        <entity-listener class="samples.MyDefaultListener1" />
        <entity-listener class="samples.MyDefaultListener2" />
      </entity-listeners>
    </persistence-unit-defaults>
  </persistence-unit-metadata>
</entity-mappings>

The mapping file has to be located either in the default location, META-INF/orm.xml, or in another location that is specified explicitly in the persistence unit definition (in persistence.xml).

Default listeners are applied by default to all the entity classes. The @ExcludeDefaultListenersjavax.persistence.ExcludeDefaultListenersJPA annotationSpecifies that the invocation of default listeners is to be excluded for the entity class (or mapped superclass) and its subclasses.
See JavaDoc Reference Page...
annotation can be used to exclude an entity class and all its descendant classes from using the default listeners:

Callback Invocation Order

If more than one callback method has to be invoked for a lifecycle event (e.g. from multiple listeners) the invocation order is based on the following rules:

  • All the external callback methods (which are defined in listeners) are invoked before the internal callback methods (which are defined in entity classes).
  • Default listeners are handled first, then listeners of the top level entity class, and then down the hierarchy until listeners of the actual entity class. If there is more than one default listener or more than one listener at the same level in the hierarchy, the invocation order follows the definition order.
  • Internal callback methods are invoked starting at the top level entity class and then down the hierarchy until the callback methods in the actual entity class are invoked.

This documentation explains how to use JPA in the context of the ObjectDB Object Database but mostly relevant
also for ORM JPA implementations, such as Hibernate (and HQL), EclipseLink, TopLink, OpenJPA and DataNucleus.
ObjectDB is not an ORM JPA implementation but an Object Database (ODBMS) for Java with built in JPA 2 support.