Tuesday, 8 February 2011

JPA Entity Lifecycle Callback and Listener Annotations

Within the javax.persistence package there are annotations that may be applied to methods of an entity or a mapped superclass to specify that the annotated method must be called for a certain lifecycle event. A lifecycle event being either: Persist, Update, Remove or Load. and each event has a Pre or Post event.

Listeners can also have methods annotated with a lifecycle event. Listeners can be used to hold the business logic that would otherwise be in the entities (or another layer.) This enables the entities to be just POJOs. It also means that the testing of the business logic can be done in isolation.

Below is an example of using lifecycle events to populate an id var and also populate a lastUpdated var, in a mapped superclass:

public abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final int ID_LENGTH=36;

    @Column(length = ID_LENGTH)
    private String id;

    @Column(updatable = false)
    private Date dateCreated;
    private Date lastModified;

    // constructor(s)

    public void updateLastModified () {
        lastModified = new Date();

    protected void generateUUID() {
        id = java.util.UUID.randomUUID().toString();       
        dateCreated = new Date();
        lastModified = new Date();



An simple example of using a Listener could be where an entity has a transient var that needs to be populated after the entity has been persisted, updated or loaded.

public class AvailableCreditListener {

    public void calculateAvailableCredit{Account account) {




The entity class would be annotated with @EntityListeners:

public class AccountEntity extends BaseEntity {

    private BigDecimal balance;
    private BigDecimal overdraftLimit;
    private BigDecimal availableCredit;

    // getters and setters


Finally, instead of annotations, an XMl mapping file can be used and deployed with the application to specify default listeners. (This mapping file is referenced by the persistence.xml file.) But an entity can use the @ExcludeDefaultListeners annotation if it does not want to use the default listeners.

public class AccountEntity extends BaseEntity {