EntityListeners in your Entity made simple

It is often useful for the application to react to certain events that happen inside the persistence mechanism. The JPA specification provides a simple mechanism for that: you can add the  @EntityListeners annotation to capture persistence events in callback methods.

Example: Consider the following Note class:

  
import java.io.Serializable;     
import javax.persistence.Entity;   
import javax.persistence.GeneratedValue;   
import javax.persistence.Id;   
import javax.persistence.Table;   
  
@Entity  
@Table(name = "NOTE")   
@EntityListeners(NoteCallbackListener.class)
  
public class Note implements Serializable {   
long noteId;   
  
String text;   
  
String actor;   
  
String attachment;   
  
@Id  
@GeneratedValue  
public long getNoteId() {   
 return noteId;   
}   
  
public void setNoteId(long noteId) {   
 this.noteId = noteId;   
}   
  
public String getActor() {   
 return actor;   
}   
  
public void setActor(String actor) {   
 this.actor = actor;   
}   
  
public String getAttachment() {   
 return attachment;   
}   
  
public void setAttachment(String attachment) {   
 this.attachment = attachment;   
}   
  
public String getText() {   
 return text;   
}   
  
public void setText(String text) {   
 this.text = text;   
}   
}

and this is the Class holding the listener:

import javax.persistence.PreRemove;
import javax.persistence.PostRemove;
import javax.persistence.PreUpdate;
import javax.persistence.PostUpdate;
import javax.persistence.PostLoad;
import javax.persistence.PrePersist;
import javax.persistence.PostPersist;

public class NoteCallbackListener
{
   @PrePersist
   public void doPrePersist(Note note)
   {
      System.out.println("doPrePersist: About to create Note: " + Note.getId());
   }

   @PostPersist
   public void doPostPersist(Object Note)
   {
      System.out.println("doPostPersist: Created Note: " + ((Note)Note).getId()));
   }

   @PreRemove
   public void doPreRemove(Note note)
   {
      System.out.println("doPreRemove: About to delete Note: " + Note.getId());
   }

   @PostRemove
   public void doPostRemove(Note note)
   {
      System.out.println("doPostRemove: Deleted Note: " + Note.getId());
   }

   @PreUpdate
   public void doPreUpdate(Note note)
   {
      System.out.println("doPreUpdate: About to update Note: " + Note.getId());
   }

   @PostUpdate
   public void doPostUpdate(Note note)
   {
      System.out.println("doPostUpdate: Updated Note: " + Note.getId());
   }

   @PostLoad
   public void doPostLoad(Note note)
   {
      System.out.println("doPostLoad: Loaded Note: " + Note.getId());
   }

And this is the description of callback methods:

TypeDescription
@PrePersistExecuted before the entity manager persist operation is actually executed or cascaded. This call is synchronous with the persist operation.
@PreRemoveExecuted before the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation.
@PostPersistExecuted after the entity manager persist operation is actually executed or cascaded. This call is invoked after the database INSERT is executed.
@PostRemoveExecuted after the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation.
@PreUpdateExecuted before the database UPDATE operation.
@PostUpdateExecuted after the database UPDATE operation.
@PostLoadExecuted after an entity has been loaded into the current persistence context or an entity has been refreshed.

Injection in Entity Listeners (JPA 2.1)

The integration of Entity Listeners with CDI has been improved with JPA 2.1. You can now use CDI to inject beans into EntityListeners and to implement the @PreDestroy and @PostConstruct methods.

Here is an example:

public class MyEntityListener {

    @Inject 
    private DemoService demoService;  // @Stateless EJB

    @PrePersist
    public void prePersist(MyEntity entity) {
        demoService.doSomething();  
    }
}