Hibernate.orgCommunity Documentation
It is often useful for the application to react to certain events that occur inside the persistence mechanism. This allows the implementation of certain kinds of generic functionality, and extension of built-in functionality. The JPA specification provides two related mechanisms for this purpose.
A method of the entity may be designated as a callback method to
receive notification of a particular entity life cycle event. Callbacks
methods are annotated by a callback annotation. You can also define an
entity listener class to be used instead of the callback methods defined
directly inside the entity class. An entity listener is a stateless class
with a no-arg constructor. An entity listener is defined by annotating the
entity class with the @EntityListeners
annotation:
@Entity
@EntityListeners(class=Audit.class)
public class Cat {
@Id private Integer id;
private String name;
private Calendar 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() );
}
}
The same callback method or entity listener method can be annotated
with more than one callback annotation. For a given entity, you cannot
have two methods being annotated by the same callback annotation whether
it is a callback method or an entity listener method. A callback method is
a no-arg method with no return type and any arbitrary name. An entity
listener has the signature void <METHOD>(Object)
where
Object is of the actual entity type (note that Hibernate Entity Manager
relaxed this constraint and allows Object
of
java.lang.Object
type (allowing sharing of listeners
across several entities.)
A callback method can raise a
RuntimeException
. The current transaction, if any,
must be rolled back. The following callbacks are defined:
Table 6.1. Callbacks
Type | Description |
---|---|
@PrePersist | Executed before the entity manager persist operation is actually executed or cascaded. This call is synchronous with the persist operation. |
@PreRemove | Executed before the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation. |
@PostPersist | Executed after the entity manager persist operation is actually executed or cascaded. This call is invoked after the database INSERT is executed. |
@PostRemove | Executed after the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation. |
@PreUpdate | Executed before the database UPDATE operation. |
@PostUpdate | Executed after the database UPDATE operation. |
@PostLoad | Executed after an entity has been loaded into the current persistence context or an entity has been refreshed. |
A callback method must not invoke
EntityManager
or Query
methods!
You can define several entity listeners per entity at different level of the hierarchy. You can also define several callbacks at different level of the hierarchy. But you cannot define two listeners for the same event in the same entity or the same entity listener.
When an event is raised, the listeners are executed in this order:
@EntityListeners
for a given entity or
superclass in the array order
Entity listeners for the superclasses (highest first)
Entity Listeners for the entity
Callbacks of the superclasses (highest first)
Callbacks of the entity
You can stop the entity listeners inheritance by using the
@ExcludeSuperclassListeners
, all superclasses
@EntityListeners
will then be ignored.
The JPA specification allows annotation overriding through JPA deployment descriptors. There is also an additional feature that can be useful: default event listeners.
<?xml version="1.0" encoding="UTF-8"?>
<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 orm_2_0.xsd"
version="2.0"
>
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="org.hibernate.ejb.test.pack.defaultpar.IncrementListener">
<pre-persist method-name="increment"/>
</entity-listener>
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
<package>org.hibernate.ejb.test.pack.defaultpar</package>
<entity class="ApplicationServer">
<entity-listeners>
<entity-listener class="OtherIncrementListener">
<pre-persist method-name="increment"/>
</entity-listener>
</entity-listeners>
<pre-persist method-name="calculate"/>
</entity>
</entity-mappings>
You can override entity listeners on a given entity. An entity listener correspond to a given class and one or several event fire a given method call. You can also define event on the entity itself to describe the callbacks.
Last but not least, you can define some default entity listeners
that will apply first on the entity listener stack of all the mapped
entities of a given persistence unit. If you don't want an entity to
inherit the default listeners, you can use
@ExcludeDefaultListeners
(or
<exclude-default-listeners/>).
Copyright © 2005 Red Hat Inc. and the various authors