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:
| 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. |
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();
}
}