The purpose of this blog entry is to provide one solution for using JPA Annotations with Hibernate but without using the Hibernate EntityManager. Thanks to Ben Macfarlane for posing this problem and for doing the groundwork for me to come up with a somewhat simple solution.
If you want to look right away at working code that compares the configuration of JPA callbacks with the EntityManager and the Hibernate SessionFactory, a sample project based on this tutorial is available.
Create a Maven Project:
We will start with a boilerplate Maven project that includes dependencies on Spring, Hibernate and JUnit.
Create a Domain and Domain Access:
Our domain can be as simple as a single POJO that uses javax.persistence annotations such as @PrePersist, @PreUpdate and @PostLoad.
A DAO and Service can provide access into our domain.
Wire It Together With Spring:
We will use Spring to glue all our components together and to manage their lifecycles.
Test The JPA Callbacks:
Finally we can test that the annotated methods are called at the expected times during Hibernate lifecycle events.
We should expect all these tests to fail with a Hibernate validation Exception.
Update Project Dependencies:
Fortunately, the hibernate-entitymanager component provides a set of JPA lifecycle listeners that can be used independent of the Hibernate EntityManager, so we will update our project dependencies.
NB: for this sample code, the version must be 3.6.x+ in order to access the ReflectionManager from the Hibernate configuration.
Register Hibernate Event Listeners:
We must manually tie the JPA lifecycle listeners to Hibernate events, much as the org.hibernate.ejb.EventListenerConfigurator#configure would if the Hibernate EntityManager were used.
Finally, we will update the Hibernate configuration in the Spring context to use these event listeners. This configuration is based off a similar solution on the Spring Forum.
NB: This configuration is for a subset of javax.persistence annotations and should be considered a starting point. It is up to the reader to configure Hibernate to use other other listeners in the org.hibernate.ejb.event package if the enablement of more JPA annotations is desired. For the purpose of this tutorial, the three listeners above are sufficient.
The test cases now succeed.
The purpose of this tutorial has been to demonstrate that, with minimal code and configuration additional to what is necessary for a standard Maven/Spring/Hibernate project, Hibernate can detect JPA annotations and tie them to its persistence lifecycle events. Along the way, we have also developed a simple methodology for testing that JPA annotated methods are called when expected, and this methodology can be used to extend the sample code to cover the remaining javax.persistence annotations not specified in this tutorial.
Sample code based on this tutorial is also available.