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.
This page covers the following topics:
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:
@Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity. public static class MyEntityWithCallbacks { @PrePersistjavax.persistence.PrePersist - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPrePersist() {} @PostPersistjavax.persistence.PostPersist - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPostPersist() {} @PostLoadjavax.persistence.PostLoad - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPostLoad() {} @PreUpdatejavax.persistence.PreUpdate - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPreUpdate() {} @PostUpdatejavax.persistence.PostUpdate - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPostUpdate() {} @PreRemovejavax.persistence.PreRemove - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPreRemove() {} @PostRemovejavax.persistence.PostRemove - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPostRemove() {} }
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:
@PrePersist
javax.persistence.PrePersist - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. - before a new entity is persisted (added to theEntityManager
).@PostPersist
javax.persistence.PostPersist - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. - after storing a new entity in the database (duringcommit
orflush
).@PostLoad
javax.persistence.PostLoad - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. - after an entity has been retrieved from the database.@PreUpdate
javax.persistence.PreUpdate - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. - when an entity is identified as modified by theEntityManager
.@PostUpdate
javax.persistence.PostUpdate - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. - after updating an entity in the database (duringcommit
orflush
).@PreRemove
javax.persistence.PreRemove - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. - when an entity is marked for removal in the EntityManager.@PostRemove
javax.persistence.PostRemove - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. - after deleting an entity from the database (duringcommit
orflush
).
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 EntityManager
javax.persistence.EntityManager - JPA InterfaceInterface used to interact with the persistence context. or Query
javax.persistence.Query - JPA InterfaceInterface used to control query execution.javax.jdo.Query - JDO InterfaceThe Query
interface allows applications to obtain persistent instances, values, and aggregate data from the data store. 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:
public class MyListener { @PrePersistjavax.persistence.PrePersist - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPrePersist(Object o) {} @PostPersistjavax.persistence.PostPersist - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPostPersist(Object o) {} @PostLoadjavax.persistence.PostLoad - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPostLoad(Object o) {} @PreUpdatejavax.persistence.PreUpdate - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPreUpdate(Object o) {} @PostUpdatejavax.persistence.PostUpdate - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPostUpdate(Object o) {} @PreRemovejavax.persistence.PreRemove - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPreRemove(Object o) {} @PostRemovejavax.persistence.PostRemove - JPA AnnotationSpecifies a callback method for the corresponding lifecycle event. void onPostRemove(Object o) {} }
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 @EntityListeners
javax.persistence.EntityListeners - JPA AnnotationSpecifies the callback listener classes to be used for an entity or mapped superclass. annotation:
@Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity. @EntityListenersjavax.persistence.EntityListeners - JPA AnnotationSpecifies the callback listener classes to be used for an entity or mapped superclass.(MyListener.class) public class MyEntityWithListener { }
Multiple listener classes can also be attached to one entity class:
@Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity. @EntityListenersjavax.persistence.EntityListeners - JPA AnnotationSpecifies the callback listener classes to be used for an entity or mapped superclass.({MyListener1.class, MyListener2.class}) public class MyEntityWithTwoListeners { }
Listeners that are attached to an entity class are inherited by its subclasses unless the subclass excludes inheritance explicitly using the @ExcludeSuperclassListeners
javax.persistence.ExcludeSuperclassListeners - JPA AnnotationSpecifies that the invocation of superclass listeners is to be excluded for the entity class (or mapped superclass) and its subclasses. annotation:
@Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity. @ExcludeSuperclassListenersjavax.persistence.ExcludeSuperclassListeners - JPA AnnotationSpecifies that the invocation of superclass listeners is to be excluded for the entity class (or mapped superclass) and its subclasses. public class EntityWithNoListener extends EntityWithListener { }
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 @ExcludeDefaultListeners
javax.persistence.ExcludeDefaultListeners - JPA AnnotationSpecifies that the invocation of default listeners is to be excluded for the entity class (or mapped superclass) and its subclasses. annotation can be used to exclude an entity class and all its descendant classes from using the default listeners:
@Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity. @ExcludeDefaultListenersjavax.persistence.ExcludeDefaultListeners - JPA AnnotationSpecifies that the invocation of default listeners is to be excluded for the entity class (or mapped superclass) and its subclasses. public class NoDefaultListenersForThisEntity { } @Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity. public class NoDefaultListenersForThisEntityEither extends NoDefaultListenersForThisEntity { }
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.