Spring MVC and Hibernate Transaction Tutorial with Examples
1. Introduction
The document is based on:
Spring 4 MVC (XML Config)
Spring AOP (Config)
Hibernate 4
In this document I will guide you to create a project using:
- Spring MVC
- Hibernate
- Spring Transaction sử dụng AOP
Using "Spring Hibernate Transaction" means that you grant the open/close authority of a transaction for Spring, and you don't need to care about handling it.
This is a typical code part. When you use Hibernate, you have to start 1 transaction and close it after you finish it..
This is a typical code part. When you use Hibernate, you have to start 1 transaction and close it after you finish it..
Session session = sessionFactory.getCurrentSession();
try {
session.getTransaction().begin();
// Todo something here
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
The above manipulation is manual, and it has difficulties in handling professional situations on various methods. Suppose A person send money to B person. You have write two methods. The first method is to debit the A person's account. The second method is to credit the B person's account. These two methods must belong to a Transaction.
Spring AOP allows the configuration to help you manage the Transaction automatically.
Spring AOP allows the configuration to help you manage the Transaction automatically.
AOP is an aspect-oriented programming. You may not need to understand it, but you learn how to configure Spring AOP for your purpose. However, if you really want to know what AOP can do, you can see the AOP document at:
2. SQL Script
ORACLE:
create table DEPARTMENT (
DEPT_ID number(10,0) not null,
DEPT_NAME varchar2(255 char) not null,
DEPT_NO varchar2(20 char) not null unique,
LOCATION varchar2(255 char),
primary key (DEPT_ID)
);
MySQL:
create table DEPARTMENT (
DEPT_ID integer not null,
DEPT_NAME varchar(255) not null,
DEPT_NO varchar(20) not null,
LOCATION varchar(255),
primary key (DEPT_ID),
unique (DEPT_NO)
);
SQLServer:
Create table DEPARTMENT (
DEPT_ID int not null,
DEPT_NAME varchar(255) not null,
DEPT_NO varchar(20) not null,
LOCATION varchar(255),
primary key (DEPT_ID),
unique (DEPT_NO)
);
3. Create project
- File/New/Other..
Enter:
- Group ID: org.o7planning
- Artifact ID: SpringMVCHibernateTransaction
- Package: org.o7planning.tutorial.springhibernate
Project was created.
Do not worry with the error message when Project has been created. The reason is that you have not declared Servlet library.
Note:
Eclipse 4.4 (Luna) create Maven project structure may be wrong. You need to check.
Eclipse 4.4 (Luna) create Maven project structure may be wrong. You need to check.
4. Configuring Maven
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.o7planning</groupId>
<artifactId>SpringMVCHibernateTransaction</artifactId>
<packaging>war</packaging>
<version>1.0.0</version>
<name>SpringMVCHibernateTransaction Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<java-version>1.7</java-version>
</properties>
<repositories>
<!-- Repository for ORACLE JDBC Driver -->
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Servlet API -->
<!-- http://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Jstl for jsp page -->
<!-- http://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- JSP API -->
<!-- http://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- Spring dependencies -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<!-- Hibernate -->
<!-- http://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.8.Final</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.8.Final</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.8.Final</version>
</dependency>
<!-- MySQL JDBC driver -->
<!-- http://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<!-- Oracle JDBC driver -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<!-- SQLServer JDBC driver (JTDS) -->
<!-- http://mvnrepository.com/artifact/net.sourceforge.jtds/jtds -->
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<build>
<finalName>SpringMVCHibernateTransaction</finalName>
<plugins>
<!-- Config: Maven Tomcat Plugin -->
<!-- http://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- Config: contextPath and Port (Default - /SpringMVCHibernateTransaction : 8080) -->
<!--
<configuration>
<path>/</path>
<port>8899</port>
</configuration>
-->
</plugin>
</plugins>
</build>
</project>
5. Configuring Spring
Configure web.xml.
SpringContextListener will read the configuration file by parameter contextConfigLocation:
SpringContextListener will read the configuration file by parameter contextConfigLocation:
WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Other XML Configuration -->
<!-- Load by Spring ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/data-source-hiber-cfg.xml,
/WEB-INF/dao-cfg.xml
/WEB-INF/transaction-cfg.xml
</param-value>
</context-param>
<!-- Spring ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
Configure Spring MVC:
WEB-INF/spring-mvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<context:component-scan base-package="org.o7planning.tutorial.springhibernate.*" />
<context:annotation-config />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
The Datasource and Hibernate configuration in file:
Here I configure Hibernate by the way of Spring. However, you can configure Hibernate in hibernate.cfg.xml file by the conventional way of Hibernate, then you notify the position to Spring (See the below Appendix).
- WEB-INF/data-source-hiber-cfg.xml
Here I configure Hibernate by the way of Spring. However, you can configure Hibernate in hibernate.cfg.xml file by the conventional way of Hibernate, then you notify the position to Spring (See the below Appendix).
NOTE: Because you want Spring to manage Transaction, you should not configure in the Hibernate configuration.
<
property
name
=
"current_session_context_class"
>thread</
property
>
WEB-INF/data-source-hiber-cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:db11g" />
<property name="username" value="simplehr" />
<property name="password" value="12345" />
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
<value>org.o7planning.entity.Department</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
</beans>
Configure Transaction Manager (Spring AOP)
WEB-INF/transaction-cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<import resource="data-source-hiber-cfg.xml"/>
<tx:annotation-driven proxy-target-class="true" transaction-manager="txManager"/>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
</beans>
Configure other beans:
WEB-INF/dao-cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<bean id="departmentDAO" class="org.o7planning.dao.impl.DepartmentDAOImpl">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</beans>
6. Java Classes
Class Entity: Department
Department.java
package org.o7planning.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name = "DEPARTMENT", uniqueConstraints = { @UniqueConstraint(columnNames = { "DEPT_NO" }) })
public class Department {
private Integer deptId;
private String deptNo;
private String deptName;
private String location;
public Department() {
}
public Department(Integer deptId, String deptName, String location) {
this.deptId = deptId;
this.deptNo = "D" + this.deptId;
this.deptName = deptName;
this.location = location;
}
@Id
@Column(name = "DEPT_ID")
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
@Column(name = "DEPT_NO", length = 20, nullable = false)
public String getDeptNo() {
return deptNo;
}
public void setDeptNo(String deptNo) {
this.deptNo = deptNo;
}
@Column(name = "DEPT_NAME", nullable = false)
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Column(name = "LOCATION")
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
DepartmentDAO.java
package org.o7planning.dao;
import java.util.List;
import org.o7planning.entity.Department;
public interface DepartmentDAO {
public List<Department> listDepartment() ;
public Integer getMaxDeptId();
public void createDepartment(String name,String location);
}
DepartmentDAOImpl.java
package org.o7planning.dao.impl;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.dao.DepartmentDAO;
import org.o7planning.entity.Department;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class DepartmentDAOImpl implements DepartmentDAO {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@SuppressWarnings("unchecked")
public List<Department> listDepartment() {
Session session = this.sessionFactory.getCurrentSession();
List<Department> list = session.createQuery("from Department").list();
return list;
}
public Integer getMaxDeptId() {
Session session = this.sessionFactory.getCurrentSession();
String sql = "Select max(d.deptId) from Department d ";
Query query = session.createQuery(sql);
Integer maxDeptId = (Integer) query.uniqueResult();
if (maxDeptId == null) {
return 0;
}
return maxDeptId;
}
public void createDepartment(String name, String location) {
Integer deptId = getMaxDeptId() + 1;
Department dept = new Department();
dept.setDeptId(deptId);
dept.setDeptNo("D" + deptId);
dept.setDeptName(name);
dept.setLocation(location);
Session session = this.sessionFactory.getCurrentSession();
session.persist(dept);
}
}
You can see a notice on Eclipse that methods are influenced by AOP (As the below illustration).
As you know, you can do the configuration in xml file in order to inform Spring that some class is a Bean. Another way is that other classes enclosed with a @Controller or @Service annotation in the scanning scope of Spring are also considered as Beans by Spring.
@Autowired annotation is attached to fields belonging to Controller class or Service class for ordering Spring automatically to have a dependency injection.
@Autowired annotation is attached to fields belonging to Controller class or Service class for ordering Spring automatically to have a dependency injection.
<!-- See the configuration code scanning range of Spring -->
<!-- spring-mvc-servlet.xml -->
<context:component-scan base-package="org.o7planning.tutorial.springhibernate.*" />
The class annotated by @Controller or @Service be regarded as the Bean, and Spring will automatically inject dependencies in the Field annotated by @Autowired annotation.
MainController.java
package org.o7planning.tutorial.springhibernate.controller;
import java.util.List;
import org.o7planning.dao.DepartmentDAO;
import org.o7planning.entity.Department;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MainController {
@Autowired
private DepartmentDAO departmentDAO;
@RequestMapping({ "/", "/home", "/index" })
public String home(Model model) {
return "index";
}
@RequestMapping({ "/deptList" })
public String deptList(Model model) {
departmentDAO.createDepartment("Dept Name", "Dept Location");
List<Department> list = departmentDAO.listDepartment();
for (Department dept : list) {
System.out.println("Dept No " + dept.getDeptNo());
}
model.addAttribute("departments", list);
return "deptList";
}
}
7. Views
index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Home</title>
</head>
<body>
<div align="center">
<h1>Home Page</h1>
<a href="deptList">Department List</a>
</div>
</body>
</html>
deptList.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Department List</title>
</head>
<body>
<div align="center">
<h1>Department List</h1>
<table border="1">
<th>No</th>
<th>Dept No</th>
<th>Dept Name</th>
<th>Location</th>
<c:forEach var="dept" items="${departments}" varStatus="status">
<tr>
<td>${status.index + 1}</td>
<td>${dept.deptNo}</td>
<td>${dept.deptName}</td>
<td>${dept.location}</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
8. Run Application
In the first, before running the application you need to build the entire project.
Right-click the project and select:
Run Configurations:
Enter:
- Name: Run SpringMVCHibernateTransaction
- Base directory: ${workspace_loc:/SpringMVCHibernateTransaction}
- Goals: tomcat7:run
9. Appendix
Datasource & Hibernate configuration for MySQL:
WEB-INF/data-source-hiber-cfg.xml (MySQL)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/simplehr" />
<property name="username" value="root" />
<property name="password" value="12345" />
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
<value>org.o7planning.entity.Department</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
</beans>
WEB-INF/data-source-hiber-cfg.xml (SQLServer)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
<property name="url" value="jdbc:jtds:sqlserver://localhost:1433/simplehr;instance=SQLEXPRESS" />
<property name="username" value="sa" />
<property name="password" value="12345" />
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
<value>org.o7planning.entity.Department</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
</beans>
Spring MVC Tutorials
- Spring Tutorial for Beginners
- Install Spring Tool Suite for Eclipse
- Spring MVC Tutorial for Beginners - Hello Spring 4 MVC
- Configure Static Resources in Spring MVC
- Spring MVC Interceptors Tutorial with Examples
- Create a Multiple Languages web application with Spring MVC
- Spring MVC File Upload Tutorial with Examples
- Simple Login Java Web Application using Spring MVC, Spring Security and Spring JDBC
- Spring MVC Security with Hibernate Tutorial with Examples
- Spring MVC Security and Spring JDBC Tutorial (XML Config)
- Social Login in Spring MVC with Spring Social Security
- Spring MVC and Velocity Tutorial with Examples
- Spring MVC and FreeMarker Tutorial with Examples
- Use Template in Spring MVC with Apache Tiles
- Spring MVC and Spring JDBC Transaction Tutorial with Examples
- Use Multiple DataSources in Spring MVC
- Spring MVC and Hibernate Transaction Tutorial with Examples
- Spring MVC Form Handling and Hibernate Tutorial with Examples
- Run background scheduled tasks in Spring
- Create a Java Shopping Cart Web Application using Spring MVC and Hibernate
- Simple CRUD example with Spring MVC RESTful Web Service
- Deploy Spring MVC on Oracle WebLogic Server
Show More