This is sort of a follow up post for a previous post of mine – RESTful Web Services Example in Java with Jersey, Spring and MyBatis. It is based on the same example application, which, via a REST API, can execute CRUD operations against a single Podcasts table. If in the first post the focus was on how to build the REST API with Jersey, this time it is on the data persistence layer. I will present how to implement a container-agnostic persistence layer with JPA2/Hibernate, being glued in the application via Spring.
1. Architecture and technologies
1.1. Architecture
1.2. Technologies used
Jersey 2.4
Spring 3.2
JPA 2
Maven 3
Tomcat 7
Jetty 9
MySql 5.6
Hibernate 4
2. Source Code
If you want to follow along, you find all you need on GitHub:
https://github.com/amacoder/demo-restWS-spring-jersey-jpa2-hibernate
MySQL DB creation self-contained file – everything is configured for the username/password : rest_demo/rest_demo
3. The coding
3.1. Configuration
3.1.1. Project dependencies
I use Maven to build the project. In addition to Spring Core and persistence dependencies, we also need to define Hibernate in the pom.xml:
Code alert: If you want to see what other dependencies (Jersey, Spring, Jetty, testing etc.) are used in the project or how the jetty-maven-plugin is configured so that you can start the project in Jetty directly from Eclipse, you can download the complete pom.xml file from GitHub – https://github.com/amacoder/demo-restWS-spring-jersey-jpa2-hibernate/blob/master/pom.xml
3.1.2. Spring application context configuration
The Spring application context configuration is located at classpath:spring/applicationContext.xml:
Relevant JPA beans:
transactionManager – note that the transaction manager used is JpaTransactionManager, instead of the DataSourceTransactionManager, which was the case when building the persistence layer with MyBatis.
entityManagerFactory – the LocalContainerEntityManagerFactoryBean gives full control over EntityManagerFactory configuration and is appropriate for environments where fine-grained customization is required. It is a FactoryBean that creates a JPA EntityManagerFactory according to JPA’s standard container bootstrap contract. This is the most powerful way to set up a shared JPA EntityManagerFactory in a Spring application context; the EntityManagerFactory can then be passed to JPA-based DAOs via dependency injection.
persistenceXmlLocation – Set the location of the persistence.xml file we want to use. This is a Spring resource location. Default is classpath:META-INF/persistence.xml.
jpaVendorAdapter – the HibernateJpaVendorAdapter setup to recognize the MySQL dialect
Note that switching to a JNDI lookup or to a LocalEntityManagerFactoryBean definition, which are the other two options to setup JPA in a Spring environment, is just a matter of configuration!
3.2. The Data Persistence layer
As mentioned before the data persistence layer permits CRUD operations against the database and is triggered via REST requests.
There have been lots of discussions whether using DAOs is still relevant when using JPA – you can find some resources on this topic at the end of the post. I, for one, still employ DAOs, as I don’t like my service classes cluttered with EntityManager/JPA specific code. What if I want to use MyBatis or other persistence technology?
So the contract between the service layer and the data persistence layer is done via the PodcastDao interface:
For this interface I provide a PodcastDaoJPA2Impl JPA-specific implementation class:
Code alert: You can find the complete implementation of PodcastDaoJPA2Impl on GitHub – I will present the code split and give some JPA related explanations bellow.
EntityManager
The EntityManager API is used to access a database in a particular unit of work. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. This interface is similar to the Session in Hibernate.
Persistence context
A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle is managed by a particular entity manager. The scope of this context can either be the transaction, or an extended unit of work.
Note: When the persistence layer was implemented with MyBatis, there was no need to have an implementation class of the interface, as one was provided at runtime via the MapperFactoryBean. See my post Spring MyBatis integration example, for complete details how to integrate MyBatis in Spring.
Now let’s see how the CRUD operations are implemented with JPA:
3.2.1. CREATE
To insert an entity in the database, you can use either persist or merge, whereas if persist is sufficient you should use it. There’s a nice article, JPA: persisting vs. merging entites, that explains the difference between the two. In my case persist was enough.
I use the flush() method of the EntityManager to force the insertion of the entity and synchronize the persistence context with the underlying database, so that I can return the new id of podcast being inserted.
Note: The transaction context is set via the @Transcational Spring annotation at the caller of the DAO class – PodcastRestService:
Please see these articles: JPA 2 | EntityManagers, Transactions and everything around it and Java Persistence/Transactions for a better understanding of the JPA mechanismus for transactions.
3.2.2. READ
For the reading operations I use TypedQuery, which is an extension of the java.persistence.Query, and, as the name suggets, knows the type it returns as a result of its execution.
3.2.3. UPDATE
To update the podcast I simply use the merge method of the EntityManager.
3.2.4. DELETE
The deletion of an entity is executed with the remove method of the EntityManager, after the entity has been loaded into the PersistenceContext with the help of the find method.
For the deletion of all podcasts, I used a TRUNCATE command against the MySQL database. Native queries are made possible via the createNativeQuery method of the EntityManager.
Well, that’s it. You’ve seen how to configure Spring with JPA/Hibernate to build the data persistence layer of an application, and how to use simple methods of the EntityManager to execute CRUD operations against a database.
If you’ve found some usefulness in this post this, I’d be very grateful if you’d help it spread by sharing it on Twitter, Google+ or Facebook. Thank you! Don’t forget also to check out Podcastpedia.org – you’ll find for sure interesting podcasts and episodes. We are grateful for your support.
4. Resources
4.1. Source Code
https://github.com/amacoder/demo-restWS-spring-jersey-tomcat-mybatis
https://github.com/amacoder/demo-restWS-spring-jersey-tomcat-mybatis/tree/master/src/main/resources/input_data (create db schema and restore data .sql files)
4.2. JPA resources
Java Persistence – open book
Spring ORM-JPA
Has JPA Killed the DAO?
Java Persistance API – Wikipedia.org
Data Access Object (DAO)
CRUD – Wikipedia
http://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/architecture.html
JPA: persisting vs. merging entites
JPA 2 | EntityManagers, Transactions and everything around it
Java Persistence/Transactions
Transaction configuration with JPA and Spring 3.1
Spring 3 and JPA with Hibernate
4.3. Rest resources
http://en.wikipedia.org/wiki/Representational_State_Transfer
http://en.wikipedia.org/wiki/Create,_read,_update_and_delete
Java API for RESTful Services (JAX-RS)
Jersey – RESTful Web Services in Java
HTTP Status Code Definitions
4.4. Codingpedia related resources
RESTful Web Services Example in Java with Jersey, Spring and MyBatis
Spring MyBatis integration example
Adrian Matei is the creator of Podcastpedia.org and Codingpedia.org, computer science engineer, husband, father, curious and passionate about science, computers, software, education, economics, social equity, philosophy.
Get connected on
Adrian’s favorite JPA and Java books (affiliate links)
Appendix
A – testing the demo application with DEV HTTP Client