Spring 4 MVC + JPA 2 + Hibernate + MySQL Example
June 25, 2019
This page will walk through Spring 4 MVC, JPA 2, Hibernate and MySQL integration example with LocalEntityManagerFactoryBean and LocalContainerEntityManagerFactoryBean using JavaConfig. Spring 4 supports JPA 2. To integrate Spring with JPA, Spring provides three ways to fetch EntityManagerFactory.
1. LocalEntityManagerFactoryBean
2. LocalContainerEntityManagerFactoryBean
3. EntityManagerFactory from JNDI
Here on this page we will discuss first two options. We will use hibernate provider for the demo. Hibernate provider will be configured in JPA persistence.xml file where we define persistence unit that are used by LocalEntityManagerFactoryBean and LocalContainerEntityManagerFactoryBean to provide EntityManagerFactory. Find the complete example step by step.
Contents
- Software used in our Demo
- Project Structure in Eclipse
- Resolve Spring JPA JAR Dependency using Gradle
- Database Schema and Java Entity
- JPA persistence.xml
- Java Configuration for LocalEntityManagerFactoryBean
- Java Configuration for LocalContainerEntityManagerFactoryBean
- Java Configuration for Spring MVC
- Create DAO for Spring JPA with @PersistenceContext
- Create Controller and View
- Output
Software used in our Demo
1. Java 82. Spring 4.1.8.RELEASE
3. Tomcat 8
4. Gradle
5. Eclipse
6. MySQL 5.5
Project Structure in Eclipse
Resolve Spring JPA JAR Dependency using Gradle
build.gradleapply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'war' archivesBaseName = 'spring4' version = '1' repositories { mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter-data-jpa:1.2.7.RELEASE' compile 'org.springframework.boot:spring-boot-starter-web:1.2.7.RELEASE' compile 'javax.servlet:javax.servlet-api:3.1.0' compile 'mysql:mysql-connector-java:5.1.31' compile 'commons-dbcp:commons-dbcp:1.4' compile 'jstl:jstl:1.2' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:1.2.7.RELEASE' }
Database Schema and Java Entity
Table Schema: userCREATE TABLE `user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NULL DEFAULT NULL, `age` INT(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB;
package com.concretepage.persistence; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Table(name="user") @Entity public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="id") private int id; @Column(name="name") private String name; @Column(name="age") private int age; public User(String name, int age){ this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
JPA persistence.xml
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="localEntity"> <description>Spring JPA Demo with LocalEntityManagerFactoryBean</description> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="validate"/> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/concretepage"/> <property name="javax.persistence.jdbc.user" value="root"/> <property name="javax.persistence.jdbc.password" value=""/> </properties> </persistence-unit> <persistence-unit name="localContainerEntity"> <description>Spring JPA Demo with LocalContainerEntityManagerFactoryBean</description> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="validate"/> </properties> </persistence-unit> </persistence>
Persistence Unit for LocalEntityManagerFactoryBean
Find the persistence unit for
LocalEntityManagerFactoryBean
. Here we have configured hibernate provider and data source.
<persistence-unit name="localEntity"> <description>Spring JPA Demo with LocalEntityManagerFactoryBean</description> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="validate"/> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/concretepage"/> <property name="javax.persistence.jdbc.user" value="root"/> <property name="javax.persistence.jdbc.password" value=""/> </properties> </persistence-unit>
Persistence Unit for LocalContainerEntityManagerFactoryBean
Find the persistence unit for
LocalContainerEntityManagerFactoryBean
. Here we have only configured hibernate provider.
<persistence-unit name="localContainerEntity"> <description>Spring JPA Demo with LocalContainerEntityManagerFactoryBean</description> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="validate"/> </properties> </persistence-unit>
Java Configuration for LocalEntityManagerFactoryBean
org.springframework.orm.jpa.LocalEntityManagerFactoryBean creates JPAEntityManagerFactory
. This is the simplest way to use JPA with Spring. We can use it for standalone application or for testing purpose. We need to provide persistence unit defined in persistence.xml. For transaction management, Spring provides JpaTransactionManager
.
JPAConfigOne.java
package com.concretepage.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @ComponentScan("com.concretepage") @EnableTransactionManagement public class JPAConfigOne { @Bean public JpaTransactionManager jpaTransMan(){ JpaTransactionManager jtManager = new JpaTransactionManager( getEntityManagerFactoryBean().getObject()); return jtManager; } @Bean public LocalEntityManagerFactoryBean getEntityManagerFactoryBean() { LocalEntityManagerFactoryBean lemfb = new LocalEntityManagerFactoryBean(); lemfb.setPersistenceUnitName("localEntity"); return lemfb; } }
Java Configuration for LocalContainerEntityManagerFactoryBean
org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean createsEntityManagerFactory
with standard JPA container bootstrap contract. Using it we can setup shared JPA EntityManagerFactory
in spring application context. We can provide hibernate provider using JPA persistence.xml. We will provide data source using any connection pool provider API like apache commons BasicDataSource
.
JPAConfigTwo.java
package com.concretepage.config; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver; import org.springframework.instrument.classloading.LoadTimeWeaver; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @ComponentScan("com.concretepage") @EnableTransactionManagement public class JPAConfigTwo { @Bean public JpaTransactionManager jpaTransMan(){ JpaTransactionManager jtManager = new JpaTransactionManager( getEntityManagerFactoryBean().getObject()); return jtManager; } @Bean public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean() { LocalContainerEntityManagerFactoryBean lcemfb = new LocalContainerEntityManagerFactoryBean(); lcemfb.setDataSource(getDataSource()); lcemfb.setPersistenceUnitName("localContainerEntity"); LoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver(); lcemfb.setLoadTimeWeaver(loadTimeWeaver); return lcemfb; } @Bean public DataSource getDataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/concretepage"); dataSource.setUsername("root"); dataSource.setPassword(""); return dataSource; } }
Java Configuration for Spring MVC
Find the java configuration for Spring MVC where we are importing java configuration file created for Spring JPA integration. To testLocalEntityManagerFactoryBean
, we need to import JPAConfigOne
and to test LocalContainerEntityManagerFactoryBean
, we need to import JPAConfigTwo
file in our spring configuration file.
AppConfig.java
package com.concretepage.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @EnableWebMvc @Import(JPAConfigTwo.class) public class AppConfig { @Bean public InternalResourceViewResolver setupViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); return resolver; } }
WebAppInitializer.java
package com.concretepage.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class WebAppInitializer implements WebApplicationInitializer { public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(AppConfig.class); ctx.setServletContext(servletContext); Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); dynamic.addMapping("/"); dynamic.setLoadOnStartup(1); } }
Create DAO for Spring JPA with @PersistenceContext
Using javax.persistence.EntityManager, we interact with database to save, update or delete the data. To get theEntityManager
, we need to use @PersistenceContext
annotation.
UserDao.java
package com.concretepage.dao; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.concretepage.persistence.User; @Repository @Transactional(readOnly = false) public class UserDao { @PersistenceContext EntityManager entityManager; public void saveUserDetail(User user){ entityManager.persist(user); System.out.println("--Data Saved--"); } }
Create Controller and View
UserController.java
package com.concretepage.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import com.concretepage.dao.UserDao; import com.concretepage.persistence.User; @Controller @RequestMapping("/user") public class UserController { @Autowired private UserDao userDao; @RequestMapping public ModelAndView save(ModelAndView modelAndView) { modelAndView.setViewName("userForm"); return modelAndView; } @RequestMapping(value = "/save", method=RequestMethod.POST) public ModelAndView save(@RequestParam(value="userName") String userName, @RequestParam(value="age") int age, ModelAndView modelAndView ) { User user = new User(userName, age); userDao.saveUserDetail(user); modelAndView.addObject("userName", userName); modelAndView.setViewName("success"); return modelAndView; } }
userForm.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <html> <head><title>Save User Data</title></head> <body> <h3>Save User Data</h3> <form:form action="user/save" method="post"> User Name:<input type="text" name="userName"> <br/> Age :<input type="text" name="age"/><br/> <input type="submit" value="Submit"/> </form:form> </body> </html>
<html> <head><title>Save User Data</title></head> <body> Hello ${userName} <br/>Data saved. </body> </html>
Output
To run demo, use URL http://localhost:8080/spring4-1/userData will be saved in database.