Spring 4 + Struts 2 + Hibernate Integration Tutorial

Previously, I have covered spring 3 + hibernate integration example and struts 2 hello world example. In this tutorial, I am discussing all important points to keep in mind when integration spring framework with struts in conjunction with hibernate. Also, please note that this tutorial uses other minor yet important concepts such as logging, use of TLDs and transactions as well integrated in this tutorial. So remember to check their details as well.

In this tutorial, I am building Employee management screen with simple capabilities like get all, add and delete. It will look like this:

home screen for spring struts hibernate integration

I will discuss the integration process in following steps:

1) Integration Overview 
2) Spring + Struts Integration
3) Spring + Hibernate Integration
4) Other Integrated Functionalities
    a) Log4j
    b) TLDs
    c) Transactions
5) Important Points to Keep Remember
6) Database Schema Used in Tutorial
7) Download Sourcecode

1) Integration Overview

Before jumping into integration details, let’s identify why we need this integration in first place itself. Like Struts, Spring can also function as an MVC implementation. Both frameworks have their merits and drawbacks, still many will agree that Spring is much better and provides wider range of functionalities. For me there are only two scenarios, where you will need information given in this tutorial:

i) You have a old application written in struts and want to use spring to enhance application’s capability many folds.
ii) You really want to learn it for your own reasons.

Otherwise I am not ware of any good reason why somebody will choose struts over spring. If you know some other good reasons, please share with all of us. That will be great.

Moving on, in this tutorial I am delegating the Action management from Struts to Spring. The reason for this delegation is that, Action class when instantiated by spring context, can use all of the other features which spring provides to it’s Controller classes in it’s own MVC implementations. So you get all spring features as well as struts Action class to have controller logic including it’s ActionForm concept.

2) Spring + Struts Integration

This is core logic and starts from registering ContextLoaderListener and StrutsPrepareAndExecuteFilter in web.xml. ContextLoaderListener takes init parameter contextConfigLocation and is responsible for setup and start Spring WebApplicationContext. Now struts will take advantage of this context in spring related services specially in dependency injection.

StrutsPrepareAndExecuteFilter look up struts.xml file in classpath and configure strut’s specific things like Action mappings, global forwards and other things defined in struts.xml file.

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://www.oracle.com/java/technologies/; id="WebApp_ID" version="2.5">
    
  <display-name>Spring+Struts+Hibernate Integration Example</display-name>
  	<welcome-file-list>
  		<welcome-file>/WEB-INF/index.jsp</welcome-file>
  	</welcome-file-list>
  	
  	<!-- Specify the spring context information location;
  	Default location is applicationContext.xml file in classpath
  	 -->
  	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:beans.xml</param-value>
	</context-param>
	<!-- Bootstrap listener to start up and shut down Spring's root WebApplicationContext. -->
  	<listener>  
  		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
	</listener> 
	<!-- Handles both the preparation and execution phases of the Struts dispatching process. -->
	<filter>  
		<filter-name>struts2</filter-name>  
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
		<init-param>
			<param-name>debug</param-name>
			<param-value>0</param-value>
		</init-param>
		<init-param>
			<param-name>detail</param-name>
			<param-value>0</param-value>
		</init-param>
	</filter>  
	<filter-mapping>  
		<filter-name>struts2</filter-name>  
		<url-pattern>/*</url-pattern>  
	</filter-mapping>  
	<!-- Struts Tag Library Descriptors -->
	<jsp-config>
		<taglib>
			<taglib-uri>/tags/struts-bean</taglib-uri>
			<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
		</taglib>
		<taglib>
			<taglib-uri>/tags/struts-html</taglib-uri>
			<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
		</taglib>
		<taglib>
			<taglib-uri>/tags/struts-logic</taglib-uri>
			<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
		</taglib>
		<taglib>
			<taglib-uri>/tags/struts-nested</taglib-uri>
			<taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
		</taglib>
	</jsp-config>
</web-app>

In second step, you will have your action mappings in struts.xml file like this:

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">	

<struts>
    <!-- devMode is helpful when you want some extra logs for debugging -->
    <constant name="struts.devMode" value="false" />
    <!-- Global message resource; 
    	 Otherwise you will have seperate message resource for each Action 
    -->
    <constant name="struts.custom.i18n.resources" value="messages" /> 
    <!-- 
    	This is important if you are planning to have slashes in Action URLs
    	e.g. In this demo, employee is deleted using URL /delete/10
    	This this is set to false; then struts will try to find mapping for 
    	URL "/10" instaed of "/delete/10"
     -->
    <constant name="struts.enable.SlashesInActionNames" value="true"/>
     
    <!-- Normal Action mappings are defined here -->
	<package name="default" namespace="" extends="struts-default">
	    <!-- Two things to Notice: 
	    	 1) class is set to 'editEmployeeAction' which is bean defined by Spring context
	    	 2) We have given the method to be called here as well;
	   	-->
		<action name="list" class="editEmployeeAction" method="listEmployees">
			<result>/view/editEmployeeList.jsp</result>
		</action>
		<action name="add" class="editEmployeeAction" method="addEmployee">
			<result type="redirect">/list</result>
		</action>
		<action name="delete/*" class="editEmployeeAction" method="deleteEmployee">
		    <param name="employee.id">{1}</param>
			<result type="redirect">/list</result>
		</action>
		<action name="*" class="editEmployeeAction" method="listEmployees">
		  <result>/view/editEmployeeList.jsp</result>
		</action> 
	</package>
	
</struts>
In strut’s alone application we would have full Action Class with it’s package information in “class” attribute. Here we have given the class name as editEmployeeAction. Where is it defined? We will ask Spring to lookup for us.

Spring context file beans.xml is typical spring alone context file having all required thing for a web application to work, INCLUDING a bean definition editEmployeeAction which struts is looking for.

beans.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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop/ http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context/ http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee/ http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/lang/ http://www.springframework.org/schema/lang/spring-lang.xsd
        http://www.springframework.org/schema/tx/ http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util/ http://www.springframework.org/schema/util/spring-util.xsd">
    
    <!-- This bean has been referred fron struts.xml file; So type it correctly; -->
    <!-- Make scope prototype; This is really important. -->
    <bean name="editEmployeeAction" class="com.howtodoinjava.controller.EditEmployeeAction" scope="prototype">
	     <property name="employeeManager">
	        <ref bean="employeeManager"/>
	     </property>
    </bean>
    
    <!-- These beans are injected automatically by spring context -->
    <bean id="employeeDAO" class="com.howtodoinjava.dao.EmployeeDaoImpl">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="employeeManager" class="com.howtodoinjava.service.EmployeeManagerImpl">
        <property name="employeeDAO" ref="employeeDAO"/>
    </bean>
    
    <!-- Configure jdbc.properties -->
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:location="/WEB-INF/jdbc.properties" />
 
    <!-- Data Source configuration -->
    <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
        p:password="${jdbc.password}" />
 
	<!-- Configure hibernate session factory -->    
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
    <!-- Run SQL queries in transactions -->
    <tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
</beans>

This is all we need to do to integrate struts with spring framework. Now you action class look like this:

EditEmployeeAction.java

package com.howtodoinjava.controller;

import java.util.List;

import org.apache.log4j.Logger;

import com.howtodoinjava.entity.EmployeeEntity;
import com.howtodoinjava.service.EmployeeManager;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

public class EditEmployeeAction extends ActionSupport implements Preparable	
{
	private static final long serialVersionUID = 1L;
	
	//Logger configured using log4j
	private static final Logger logger = Logger.getLogger(EditEmployeeAction.class);
	
	//List of employees; Setter and Getter are below
	private List<EmployeeEntity> employees;
	
	//Employee object to be added; Setter and Getter are below
	private EmployeeEntity employee;
	
	//Employee manager injected by spring context; This is cool !!
	private EmployeeManager employeeManager;

	//This method return list of employees in database
	public String listEmployees() {
		logger.info("listEmployees method called");
		employees = employeeManager.getAllEmployees();
		return SUCCESS;
	}

	//This method will be called when a employee object is added
	public String addEmployee() {
		logger.info("addEmployee method called");
		employeeManager.addEmployee(employee);
		return SUCCESS;
	}

	//Deletes a employee by it's id passed in path parameter
	public String deleteEmployee() {
		logger.info("deleteEmployee method called");
		employeeManager.deleteEmployee(employee.getId());
		return SUCCESS;
	}
	
	//This method will be called before any of Action method is invoked;
	//So some pre-processing if required.
	@Override
	public void prepare() throws Exception {
		employee = null;
	}

	//Getters and Setters hidden
}

Spring also inject the DAO references to Manager class.

EmployeeManagerImpl.java

package com.howtodoinjava.service;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.howtodoinjava.dao.EmployeeDAO;
import com.howtodoinjava.entity.EmployeeEntity;

public class EmployeeManagerImpl implements EmployeeManager 
{
	//Employee dao injected by Spring context
    private EmployeeDAO employeeDAO;
	
	//This method will be called when a employee object is added
	@Override
	@Transactional
	public void addEmployee(EmployeeEntity employee) {
		employeeDAO.addEmployee(employee);
	}
	
	//This method return list of employees in database
	@Override
	@Transactional
	public List<EmployeeEntity> getAllEmployees() {
		return employeeDAO.getAllEmployees();
	}
	//Deletes a employee by it's id
	@Override
	@Transactional
	public void deleteEmployee(Integer employeeId) {
		employeeDAO.deleteEmployee(employeeId);
	}
	
	//This setter will be used by Spring context to inject the dao's instance
	public void setEmployeeDAO(EmployeeDAO employeeDAO) {
		this.employeeDAO = employeeDAO;
	}
}

3) Spring + Hibernate Integration

Now we have to integrate hibernate into application. Best place is to integrate using Spring’s extensive capabilities to work with different ORMs using excellent use of dependency injection.

Required hibernate dependencies for spring have already been given in above beans.xml file. Other files you will need are:

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
    <session-factory>
        <mapping class="com.howtodoinjava.entity.EmployeeEntity" />
    </session-factory>
</hibernate-configuration>

jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://127.0.0.1:3306/test
jdbc.username=root
jdbc.password=password

EmployeeDaoImpl.java

package com.howtodoinjava.dao;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import com.howtodoinjava.entity.EmployeeEntity;

@Repository
public class EmployeeDaoImpl implements EmployeeDAO  
{
	//Session factory injected by spring context
    private SessionFactory sessionFactory;
	
    //This method will be called when a employee object is added
	@Override
	public void addEmployee(EmployeeEntity employee) {
		this.sessionFactory.getCurrentSession().save(employee);
	}

	//This method return list of employees in database
	@SuppressWarnings("unchecked")
	@Override
	public List<EmployeeEntity> getAllEmployees() {
		return this.sessionFactory.getCurrentSession().createQuery("from EmployeeEntity").list();
	}

	//Deletes a employee by it's id
	@Override
	public void deleteEmployee(Integer employeeId) {
		EmployeeEntity employee = (EmployeeEntity) sessionFactory.getCurrentSession()
										.load(EmployeeEntity.class, employeeId);
        if (null != employee) {
        	this.sessionFactory.getCurrentSession().delete(employee);
        }
	}

	//This setter will be used by Spring context to inject the sessionFactory instance
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
}

For your reference, the EmployeeEntity class looks like this:

EmployeeEntity.java

package com.howtodoinjava.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="EMPLOYEE")
public class EmployeeEntity {
     
    @Id
    @Column(name="ID")
    @GeneratedValue
    private Integer id;
     
    @Column(name="FIRSTNAME")
    private String firstname;
 
    @Column(name="LASTNAME")
    private String lastname;
 
    @Column(name="EMAIL")
    private String email;
     
    @Column(name="TELEPHONE")
    private String telephone;
     
    //Setters and Getters
}

4) Other Integrated Functionalities

Apart from struts + spring + hibernate we have used following components to build the application.

a) Log4j

Spring configure logging automatically by scanning log4j in classpath. We have added the log4j dependency using pom.xml file. Now all you have to place a log4j.xml or log4j.properties file in classpath.

log4j.properties

log4j.rootLogger=info, stdout, R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=c:/log/demo.log
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

b) TLDs

If you look at web.xml file, the we have included some TLDs in there. We can use them anytime in view layer like this:

editEmployeeList.jsp

<%@ taglib prefix="s" uri="/struts-tags"%> 
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>Spring-4 + Struts-3 + Hibernate Integration Demo</title>
    <style>
	table.list
	{
		border-collapse:collapse;
		width: 40%;
	}
	table.list, table.list td, table.list th
	{
		border:1px solid gray;
		padding: 5px;
	}
	</style>
</head>
<body>
 
<h2>Spring-4 + Struts-3 + Hibernate Integration Demo</h2>
 
<s:form method="post" action="add">
    <table>
	    <tr>
	        <td><s:textfield key="label.firstname" name="employee.firstname"/></td> 
	    </tr>
	    <tr>
	        <td><s:textfield key="label.lastname" name="employee.lastname"/></td>
	    </tr>
	    <tr>
	        <td><s:textfield key="label.email" name="employee.email"/></td>
	    </tr>
	    <tr>
	        <td><s:textfield key="label.telephone" name="employee.telephone"/></td>
	    </tr>
	    <tr>
	        <td>
	        	<s:submit key="label.add"></s:submit>
	        </td>
	    </tr>
	</table> 
</s:form>
 
     
<h3>Employees</h3>
<c:if  test="${!empty employees}">
	<table class="list">
		<tr>
		    <th align="left">Name</th>
		    <th align="left">Email</th>
		    <th align="left">Telephone</th>
		    <th align="left">Actions</th>
		</tr>
		<c:forEach items="${employees}" var="emp">
		    <tr>
		        <td>${emp.lastname}, ${emp.firstname} </td>
		        <td>${emp.email}</td>
		        <td>${emp.telephone}</td>
		        <td><a href="delete/${emp.id}">delete</a></td>
		    </tr>
		</c:forEach>
	</table>
</c:if>
 
</body>
</html>

c) Transactions

EmployeeManagerImpl.java uses annotation @Transactional in method such as getAllEmployees() and deleteEmployee(). This essentially run all the database queries executed under this method in single transaction. You declared transaction dependencies in beans.xml context file like this.

<!-- Run SQL queries in transactions -->
<tx:annotation-driven />

<bean id="transactionManager"
	class="org.springframework.orm.hibernate3.HibernateTransactionManager">
	<property name="sessionFactory" ref="sessionFactory" />
</bean>

5) Important Points to Keep Remember

a) Add the jar files from project dependencies into project deployment assembly if runtime is unable to find classes present in lib folder.

b) Make scope of Action class defined in bean.xml as “prototype”. Default scope of Spring’s provided beans are singleton and struts Action class must be created new for each request because it contain user session specific data. To accommodate both, mark Action class bean as prototype.

c)
Do not forget to setup the database before running this application. It will cause you several exceptions if not setup correctly.

d) Also, please include struts2-spring-plugin as well in project runtime dependencies.

6) Database Schema Used in Tutorial

Following table has been created in MySQL in database named “test”.

CREATE TABLE EMPLOYEE
(
    ID          INT PRIMARY KEY AUTO_INCREMENT,
    FIRSTNAME   VARCHAR(30),
    LASTNAME    VARCHAR(30),
    TELEPHONE   VARCHAR(15),
    EMAIL       VARCHAR(30),
    CREATED     TIMESTAMP DEFAULT NOW()
);

If you are planning to build the application yourself then below given directly structure used in this application will help you.

directory structure for spring struts hibernate integration
Directory structure for spring struts hibernate integration

And the pom.xml file used in this project having all project dependencies (some extra) is as below:

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>com.howtodoinjava.app</groupId>
  <artifactId>Spring4Struts2HibernateIntegration</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Spring4Struts2HibernateIntegration Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <!-- JBoss repository for Hibernate -->
  <repositories>
	<repository>
		<id>JBoss repository</id>
		<url>http://repository.jboss.org/nexus/content/groups/public/</url>
	</repository>
  </repositories>
  <properties>
    <org.springframework.version>4.0.3.RELEASE</org.springframework.version>
  </properties>
  <dependencies>
    
	<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
	
	<dependency>
		<groupId>org.apache.struts</groupId>
		<artifactId>struts2-core</artifactId>
		<version>2.3.16.2</version>
	</dependency>
	
   <dependency>
		<groupId>org.apache.struts</groupId>
		<artifactId>struts2-spring-plugin</artifactId>
		<version>2.3.16.2</version>
	</dependency>
	
     <!--
	    Core utilities used by other modules.
	    Define this if you use Spring Utility APIs (org.springframework.core.*/org.springframework.util.*)
	-->
	<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-core</artifactId>
	  <version>${org.springframework.version}</version>
	  <scope>runtime</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>${org.springframework.version}</version>
		<scope>runtime</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>${org.springframework.version}</version>
		<scope>runtime</scope>
	</dependency>
            
	<!--
	    Bean Factory and JavaBeans utilities (depends on spring-core)
	    Define this if you use Spring Bean APIs (org.springframework.beans.*)
	-->
	<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-beans</artifactId>
	  <version>${org.springframework.version}</version>
	</dependency>
	<!--
	    Application Context (depends on spring-core, spring-expression, spring-aop, spring-beans)
	    This is the central artifact for Spring's Dependency Injection Container and is generally always defined
	-->
	<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-context</artifactId>
	  <version>${org.springframework.version}</version>
	</dependency>
	<!--
	    Aspect Oriented Programming (AOP) Framework (depends on spring-core, spring-beans)
	    Define this if you use Spring AOP APIs (org.springframework.aop.*)
	-->
	<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-aop</artifactId>
	  <version>${org.springframework.version}</version>
	</dependency>
	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjtools</artifactId>
		<version>1.6.2</version>
	</dependency>
	<dependency>
		<groupId>cglib</groupId>
		<artifactId>cglib</artifactId>
		<version>3.1</version>
	</dependency>
            
	<!--
	    Transaction Management Abstraction (depends on spring-core, spring-beans, spring-aop, spring-context)
	    Define this if you use Spring Transactions or DAO Exception Hierarchy
	    (org.springframework.transaction.*/org.springframework.dao.*)
	-->
	<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-tx</artifactId>
	  <version>${org.springframework.version}</version>
	</dependency>
	<!--
	    JDBC Data Access Library (depends on spring-core, spring-beans, spring-context, spring-tx)
	    Define this if you use Spring's JdbcTemplate API (org.springframework.jdbc.*)
	-->
	<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-jdbc</artifactId>
	  <version>${org.springframework.version}</version>
	</dependency>
	 
	<!--
	    Object-to-Relation-Mapping (ORM) integration with Hibernate, JPA, and iBatis.
	    (depends on spring-core, spring-beans, spring-context, spring-tx)
	    Define this if you need ORM (org.springframework.orm.*)
	-->
	<dependency>
	  <groupId>org.springframework</groupId>
	  <artifactId>spring-orm</artifactId>
	  <version>${org.springframework.version}</version>
	</dependency>
	
	<dependency>  
       <groupId>log4j</groupId>  
       <artifactId>log4j</artifactId>  
       <version>1.2.15</version>  
       <exclusions>  
         <exclusion>  
           <groupId>javax.mail</groupId>  
           <artifactId>mail</artifactId>  
         </exclusion>  
         <exclusion>  
           <groupId>javax.jms</groupId>  
           <artifactId>jms</artifactId>  
         </exclusion>  
         <exclusion>  
           <groupId>com.sun.jdmk</groupId>  
           <artifactId>jmxtools</artifactId>  
         </exclusion>  
         <exclusion>  
           <groupId>com.sun.jmx</groupId>  
           <artifactId>jmxri</artifactId>  
         </exclusion>  
       </exclusions>  
       <scope>runtime</scope>  
     </dependency>  
     
     <dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-core</artifactId>
		<version>3.6.3.Final</version>
	</dependency>

	<dependency>
		<groupId>javassist</groupId>
		<artifactId>javassist</artifactId>
		<version>3.12.1.GA</version>
	</dependency>
 
 	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>jstl</artifactId>
		<version>1.2</version>
		<scope>runtime</scope>
	</dependency>
	
	<dependency>
		<groupId>taglibs</groupId>
		<artifactId>standard</artifactId>
		<version>1.1.2</version>
		<scope>runtime</scope>
	</dependency>
	
	<dependency>
	  <groupId>commons-dbcp</groupId>
	  <artifactId>commons-dbcp</artifactId>
	  <version>1.4</version>
	</dependency>
        
   <dependency>
	    <groupId>mysql</groupId>
	    <artifactId>mysql-connector-java</artifactId>
	    <version>5.1.9</version>
	</dependency>
    
  </dependencies>
  <build>
    <finalName>Spring3Struts2HibernateIntegration</finalName>
    <plugins>
		<plugin>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>2.3.2</version>
			<configuration>
				<source>1.6</source>
				<target>1.6</target>
			</configuration>
		</plugin>
	</plugins>
  </build>
</project>

7) Download Sourcecode

Download sourcecode of above example or go for .war file.

That’s all for this spring 4 + struts 2 + hibernate integration tutorial. Let me know of your thoughts and queries.

Happy Learning !!

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

20 thoughts on “Spring 4 + Struts 2 + Hibernate Integration Tutorial”

  1. Hi lokesh,

    Can you please provide simple architecture diagram of above tutorial. Actually i faced this question in an interview. I am not able to answer the question. It will be very useful for others as well.

    Please help!!

    Reply
  2. org.slf4j
    slf4j-api
    1.7.2

    org.slf4j
    slf4j-log4j12
    1.7.2

    Add this dependency in the pom and remove the old one. In the DB connection properties use the default username and password. after this changes it work it work for me.

    Reply
  3. hi..im getting this error when I do maven install

    Failed to execute goal on project struts-setup: Could not resolve dependencies for project com.dilhara:struts-setup:war:0.0.1-SNAPSHOT: Could not find artifact com.sun:tools:jar:1.5.0 at specified path /usr/lib/jvm/java-6-openjdk-i386/jre/../lib/tools.jar -> [Help 1]

    and I updated pom like bellow


    com.sun
    tools
    1.5.0

    but same error is given

    Reply
  4. Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.student.dao.EmployeeDaoImpl] for bean with name ’employeeDAO’ defined in class path resource [beans.xml]; nested exception is java.lang.ClassNotFoundException: com.student.dao.EmployeeDaoImpl. Please see server.log for more details.

    help me

    Reply
  5. Thanks for this tutorial, infortunately I’m having following exception when I go to my only one url in my test webapp born from this tutorial:

    GRAVE: Servlet.service() for servlet [jsp] in context with path [/mylastbag] threw exception
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:319)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:985)
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.findEntityManagerFactory(EntityManagerFactoryUtils.java:142)
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.lookupEntityManagerFactory(OpenEntityManagerInViewFilter.java:226)
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.lookupEntityManagerFactory(OpenEntityManagerInViewFilter.java:202)
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:147)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:662)

    What could be? Thanks in advance
    Raffaele

    Reply
  6. This is an awesome tutorial. Thanks for posting it.
    I successfully managed to run the codes in Eclipse. Now, I’m facing a problem creating the unit tests. I don’t know how to inject the session factory for the DAO unit tests. It’s always null. Do you have tutorial on how to do the unit tests? Thanks.

    Reply
    • I hope you are using @RunWith annotation along with @ContextConfiguration. If you are still facing the error then please provide the sample unit testcase you have written.

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration( locations = { “classpath:zzz-context.xml” })

      Reply
      • Hi Lokesh, thanks for answering my question.

        I have just added @RunWith & @ContextConfiguration, but I encounter another issue.

        15:58:34,669 ERROR TestContextManager:334 – Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@7555b920] to prepare test instance [service.UserServiceTest@4152d38d]
        java.lang.IllegalStateException: Failed to load ApplicationContext
        at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
        at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)

        Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private dao.impl.GenericDAOImpl service.impl.GenericServiceImpl.daoClass; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [dao.impl.GenericDAOImpl] is defined: expected single matching bean but found 33: genericDAO,profileDAO,profileRoleMapDAO,roleDAO,rolePermissionMapDAO,templateDAO,userDAO
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
        … 41 more
        Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [dao.impl.GenericDAOImpl] is defined: expected single matching bean but found 33: genericDAO,profileDAO,profileRoleMapDAO,roleDAO,rolePermissionMapDAO,templateDAO,userDAO
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:970)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)

        Here is my unit test.

        BaseTest.java
        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration(locations = {“classpath:beans.xml”})
        public class BaseTest {
        }

        UserServiceTest.java
        public class UserServiceTest extends BaseTest {

        @Autowired
        private UserService userService;

        @Before
        public void setUp() {
        System.out.println(“Before”);
        userService = new UserServiceImpl();
        }

        @Test
        public void testAdd () {
        User user = new User();
        user.setEmail(“email”);
        user.setFirstName(“firstName”);
        user.setLastName(“lastName”);
        user.setPassword(“password”);
        userService.create(user);
        }

        }

        Hope you can help. Thanks.

        Reply
  7. Thank you for the nice tutorial, but why you are referencing old Struts1 tag libs the your web.xml? Also you should better use the tags provided by struts instead of from the jstl taglib. With the Struts tags you can use OGNL.

    Reply
  8. Hi ,
    I have a question, This may be General but i want to know this.

    Assume that,I have struts2 project and it integrated with hibernate and using Maven. i want migrate into
    Pure SpringMVC- hibernate. Before migrate into Spring what are the prerequisite steps i need to follow
    in terms of Live project ?

    Thanks,
    Adarsha.

    Reply
    • Adarsh, this is really a very good question. I do not have any concrete suggestion at this time and I will try to put my thoughts in this blog separately. For the sake of answering, I can only say If I have been doing it actually then first step would have been to try to divide all such struts things which spring support directly or indirectly /and which does not support by any mean.
      First take down the items which spring support and then do the hard job. Idea is simple, most of things should be achievable by changing config files.

      Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.