In a recent project I wanted to intercept Create, Update and Delete events. From the Hibernate Reference Documentation it was pretty straightforward to find out how to create an Interceptor class. I extended my AuditInterceptor class from the EmptyInterceptor interface and implemented the onSave, onFlushDirty and onDelete methods but then was a bit puzzled how to activate the interceptor. Chapter 2 talks about specific hibernate configuration properties, but how to use those when you're using a JPA persistence.xml? It turns out the answer is very simple. Pretty much any vendor specific property can be set in the persistence.xml using a properties block. In this case a property with name hibernate.ejb.interceptor needs to be set to the full name of my AuditInterceptor class.
Some advantages are that
- you don't to change any of your existing code, just add your interceptor and update the persistence.xml
- the onFlushDirty gives you a nice detailed information on what changed
- the interceptor fires for every entity bean, and chances are you're only interested in a subset. I ended up doing the filtering in my AudutInterceptor.
- if your primary key is set by the database, the id is still undefined when onSave fires.
The capabilities of Hibernate Events API goes beyond those of the Interceptors. It gives you very fine-grained control over where to hook into the event stream. Check out the org.hibernate.event package for all the different interfaces you can implement.
- fine-grained control over where to hook into the persistence process (lots of Pre- and Post-event interfaces)
- The event objects are contain a wealth of information, including previous and current state of the entity.
- hooking up your EventListener is either done programmatically or using the Hibernate session-factory configuration block. I guess I could use a hibernate.cfg.xml file and reference that in my persistence.xml, but it started to feel convoluted to me.
FInally there are non vendor specific JPA EntityListeners. To use an EntityListener you simply add a '@EntityListener (class=
Some advantages are
- fine-grained control as to which entities you want to listen to (annotation on the entity, referencing your listener class)
- pretty good control on where you want to hook in your listener (annotation on a method on the listeners class)
- the API only gives you the current state of the entity, and does not provide information as to what changed in case of an update.
In my case I ended up with a hybrid solution using a HibernateInterceptor for the Update and Delete, and using EntityListeners for the Create event, listening to the PostInsert events so that the id field on my entities are defined.