create database usersdb; CREATE TABLE `users` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(45) NOT NULL, `password` varchar(45) NOT NULL, `email` varchar(45) NOT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1Remember to insert some dummy data for testing purspose.
<properties> <java-version>1.7</java-version> <org.springframework-version>4.0.3.RELEASE</org.springframework-version> </properties>Update pom.xml file for the following dependencies:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${org.springframework-version}</version> <type>jar</type> <scope>compile</scope> </dependency>
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.5.Final</version> </dependency>
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency>
<dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.0</version> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency>
package net.codejava.spring.model; public class User { private int id; private String username; private String password; private String email; // getters and setters are removed for brevity }This model class is used to map the table users and the database to a plain-old Java object (POJO).
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="net.codejava.spring.model"> <class name="User" table="USERS"> <id name="id" column="USER_ID"> <generator class="native"/> </id> <property name="username" column="USERNAME" /> <property name="password" column="PASSWORD" /> <property name="email" column="EMAIL" /> </class> </hibernate-mapping>NOTE: For more information about Hibernate XML mapping, see: Hibernate One-to-Many XML Mapping Example.
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <mapping resource="net/codejava/spring/model/User.hbm.xml"/> </session-factory> </hibernate-configuration>This Hibernate configuration file declares which resources need to be mapped (the User.hbm.xml file in this case).
package net.codejava.spring.dao; import java.util.List; import net.codejava.spring.model.User; public interface UserDAO { public List<User> list(); }This interface declares only one method list() that retrieves all users from the database.
package net.codejava.spring.dao; import java.util.List; import net.codejava.spring.model.User; import org.hibernate.Criteria; import org.hibernate.SessionFactory; import org.springframework.transaction.annotation.Transactional; public class UserDAOImpl implements UserDAO { private SessionFactory sessionFactory; public UserDAOImpl(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override @Transactional public List<User> list() { @SuppressWarnings("unchecked") List<User> listUser = (List<User>) sessionFactory.getCurrentSession() .createCriteria(User.class) .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list(); return listUser; } }Notice in this class, a Hibernate’s SessionFactory object is injected via constructor by Spring. The list() method simply obtains the current session from the SessionFactory and queries for a list of all users in the database.Pay attention to the @Transactional annotation provided by Spring - when a method is annotated by this annotation, Spring will inject transaction support code into the method - thus we don’t have two write any code to handle transaction explicitly.
<mvc:annotation-driven /> <mvc:resources mapping="/resources/**" location="/resources/" /> <context:component-scan base-package="net.codejava.spring" />The following declaration for a common view resolver that converts logical view names to actual JSP pages:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/usersdb"/> <property name="username" value="root"/> <property name="password" value="secret"/> </bean>NOTE: Change database URL, username and password according to values in your environment. This data source will be injected to a SessionFactory bean below.
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> </bean>Note that this LocalSessionFactoryBean requires a DataSource bean which is declared previously. The configLocation property specifies where Hibernate configuration file will be searched for. In this case, it is the hibernate.cfg.xml file in the classpath.
<tx:annotation-driven /> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>As mentioned in the UserDAOImpl class, we can specify transaction support by using the @Transactional annotation for transaction-aware methods.
<bean id="userDao" class="net.codejava.spring.dao.UserDAOImpl"> <constructor-arg> <ref bean="sessionFactory" /> </constructor-arg> </bean>This bean will be then injected to a Spring MVC controller class which is described below.NOTE: For the whole content of Spring application context configuration file, see the corresponding file in the attached project.
package net.codejava.spring; import java.util.List; import net.codejava.spring.dao.UserDAO; import net.codejava.spring.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** * Handles requests for the application home page. */ @Controller public class HomeController { @Autowired private UserDAO userDao; @RequestMapping(value="/") public ModelAndView home() { List<User> listUsers = userDao.list(); ModelAndView model = new ModelAndView("home"); model.addObject("userList", listUsers); return model; } }Here, an implementation of the UserDAO is injected automatically by Spring (because @Autowired annotation is used). Remember the UserDAOImpl bean we declared in the Spring application context configuration file previously? It is injected to this controller automatically so that the handling method home() can use it to list all users from the database. And eventually, the home() method returns a view named home which is resolved an actual JSP page which is described below.
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@ 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>Contact List</h1> <table border="1"> <th>No</th> <th>Username</th> <th>Email</th> <c:forEach var="user" items="${userList}" varStatus="status"> <tr> <td>${status.index + 1}</td> <td>${user.username}</td> <td>${user.email}</td> </tr> </c:forEach> </table> </div> </body> </html>This JSP page simply displays a list of users which is passed by the controller, by using JSTL tags.
http://localhost:8080/SpringMvcHibernateXML
If everything is going fine, you would see the following result:Congratulations! You have completed our first part of Spring-Hibernate Integration series. You can download the attached project and experiment yourself. A deployable WAR file is also provided for your convenience. References: