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