Saturday, 2 December 2017

Spring MVC with Hibernate CRUD Example

      In this post, We can write a simple Spring MVC web application i.e CRUD operation using annotation based Hibernate ORM.  The CRUD operation means Add, Edit, Select and Delete. We can create web application using Spring and Hibernate as follows.

First step is to create the Dynamic Web Project in Eclipse , then configure the web.xml as follows,
The project structure i.e folder structure shown in the below image.

 Project Structure:--

Spring Crud operation project structure

Deployment Descriptor(web.xml)
 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">

 <servlet>
      <servlet-name>appln</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>/WEB-INF/appln-servlet.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
        <servlet-name>appln</servlet-name>
        <url-pattern>*.html</url-pattern>
 </servlet-mapping>

 <welcome-file-list>
        <welcome-file>add.html</welcome-file>
 </welcome-file-list>

</web-app>

       In the above configuration, most important is to give the correct spring bean configuration location otherwise it won't take configuration file. In this example, appln-servlet.xml is the bean configuration file kept inside WEB-INF folder.


Hibernate Entity Bean:--

 In the example, used annotation based Hibernate not xml configuration. The Annotation based Employee bean is as follows,


package com.adnblog.model;

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;

/**
 * @author Anil N
 *
 */
@Entity
@Table(name="Employee")
public class Employee implements Serializable{

        private static final long serialVersionUID = -723583058586873479L;
 
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        @Column(name = "emp_id")
        private Integer empId;
 
        @Column(name="emp_name")
        private String empName;
 
        @Column(name="emp_address")
        private String empAddress;
 
        @Column(name="emp_salary")
        private Long salary;
 
        @Column(name="emp_age")
        private Integer empAge;

        public Integer getEmpId() {
             return empId;
        }

        public void setEmpId(Integer empId) {
             this.empId = empId;
        }

        public String getEmpName() {
             return empName;
        }

        public void setEmpName(String empName) {
             this.empName = empName;
        }

        public String getEmpAddress() {
             return empAddress;
        }

        public void setEmpAddress(String empAddress) {
             this.empAddress = empAddress;
        }

        public Long getSalary() {
             return salary;
        }

        public void setSalary(Long salary) {
             this.salary = salary;
        }

        public Integer getEmpAge() {
             return empAge;
        }

        public void setEmpAge(Integer empAge) {
             this.empAge = empAge;
        }
}

The entity bean Employee maps with database employee table. So I'm creating an employee table is as follows.

employee table - Using PostgreSQL database.

CREATE TABLE employee (
         emp_id INTEGER PRIMARY KEY,
         emp_address CHARACTER VARYING(40),
         emp_salary BIGINT,
         emp_age INTEGER,
         emp_name CHARACTER VARYING(25)
);

create one properties file under resource folder i.e database.properties, there keep all database information as a key value pairs, and this information you can access in the bean configuration file.

database.properties

database.driver=org.postgresql.Driver
database.url=jdbc:postgresql://localhost:5432/hms
database.user=postgres
database.password=admin
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update

using PostgreSQL as database, you can use any database and configure here properly.


Hibernate DAO Class: - 

          We will create the EmployeeDao interface to declare the methods that are used in the CRUD example. Next we can implement those methods in another class.

EmployeeDao.java


package com.adnblog.dao;

import java.util.List;

import com.adnblog.model.Employee;

/**
 * @author Anil N
 *
 */
public interface EmployeeDao {
 
       public Integer addEmployee(Employee employee);

       public List<Employee> listEmployeess();
 
       public Employee getEmployee(int empid);
 
       public void updateEmployee(Employee employee);
 
       public void deleteEmployee(Employee emp);
}

Implementation class i.e EmployeeDaoImpl as follows,

EmployeeDaoImpl.java
 
package com.adnblog.dao;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.adnblog.model.Employee;

/**
 * @author Anil N
 *
 */
@Repository
public class EmployeeDaoImpl implements EmployeeDao {

       @Autowired
       private SessionFactory sessionFactory;
 
       public Integer addEmployee(Employee employee) {
            return (Integer)sessionFactory.getCurrentSession().save(employee);
       }

       public void updateEmployee(Employee employee) {
            sessionFactory.getCurrentSession().saveOrUpdate(employee);
       }
       @SuppressWarnings("unchecked")
       public List<Employee> listEmployeess() {
            return (List<Employee>) sessionFactory.getCurrentSession().createCriteria(Employee.class).list();
       }

       public Employee getEmployee(int empid) {
            return (Employee) sessionFactory.getCurrentSession().get(Employee.class, empid);
       }

       public void deleteEmployee(Employee emp) {
             sessionFactory.getCurrentSession().createQuery("DELETE FROM Employee WHERE emp_id = "+emp.getEmpId()).executeUpdate();
       }

}

We are using Spring transaction so Hibernate transaction not required.


Service Classes :--

       In Service also I created one interface, there I declared all CRUD methods. Next in implemented class implemented all methods and used Spring transaction.


EmployeeService.java


package com.adnblog.service;

import java.util.List;

import com.adnblog.model.Employee;

/**
 * @author Anil N
 *
 */
public interface EmployeeService {
 
      public Integer addEmployee(Employee employee);

      public List<Employee> listEmployeess();
 
      public Employee getEmployee(int empid);
 
      public void updateEmployee(Employee employee);
 
      public void deleteEmployee(Employee emp);
}

The implemented Service class i.e EmployeeServiceImpl is as follows, (@Transactional annotation is using for declarative transaction)

EmployeeServiceImpl.java

package com.adnblog.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.adnblog.dao.EmployeeDao;
import com.adnblog.model.Employee;

/**
 * @author Anil N
 *
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS)
public class EmployeeServiceImpl implements EmployeeService {

       @Autowired
       private EmployeeDao employeeDao;
 
       @Transactional(propagation = Propagation.REQUIRED)
       public Integer addEmployee(Employee employee) {
            return employeeDao.addEmployee(employee);
       }
 
       public List<Employee> listEmployeess() {
            return employeeDao.listEmployeess();
       }

       public Employee getEmployee(int empid) {
            return employeeDao.getEmployee(empid);
       }
       @Transactional(propagation = Propagation.REQUIRED)
       public void updateEmployee(Employee employee) {
            employeeDao.updateEmployee(employee);
       }
 
       @Transactional(propagation = Propagation.REQUIRED)
       public void deleteEmployee(Employee emp) {
            employeeDao.deleteEmployee(emp);
       }

}



Controller class:--
        The Controller class is a heart of MVC pattern, using @Controller annoation Front controller finds the appropriate controller using HandlerMapping.  It will take the request, process it and send model data to the appropriate view.

EmployeeController.java  


package com.adnblog.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
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.adnblog.bean.EmployeeBean;
import com.adnblog.model.Employee;
import com.adnblog.service.EmployeeService;

/**
 * @author Anil N
 *
 */
@Controller
public class EmployeeController {
 
       @Autowired
       private EmployeeService employeeService;
 
       @RequestMapping(value = "/add", method = RequestMethod.GET)
       public ModelAndView addEmployee(@ModelAttribute("command")  EmployeeBean employeeBean,
                        BindingResult result) {
             Map<String, Object> model = new HashMap<String, Object>();
             model.put("employee",  new EmployeeBean());
             return new ModelAndView("addEmployee", model);
       }

       @RequestMapping(value = "/edit", method = RequestMethod.GET)
       public ModelAndView editEmployee(@RequestParam("id") Integer id, 
                         @ModelAttribute("command") EmployeeBean employeeBean) {
              Map<String, Object> model = new HashMap<String, Object>();
              model.put("employee",  new EmployeeBean());
              model.put("employees", employeeService.getEmployee(id));
              return new ModelAndView("addEmployee", model);
       }
 
 
       @RequestMapping(value = "/save", method = RequestMethod.POST)
       public ModelAndView saveEmployee(@RequestParam("id") String id,
                          @ModelAttribute("command") EmployeeBean employeeBean) {
  
              Integer empId = 0;
              Employee employee = prepareModel(employeeBean, id);
              if (id != null && !id.isEmpty()) {
                     employeeService.updateEmployee(employee);
                     empId = Integer.parseInt(id);
              } else {
                     empId = employeeService.addEmployee(employee);
              }
              ModelAndView mv = new ModelAndView("redirect:/edit.html?id="+empId);
              return mv;
       }

       @RequestMapping(value="/list", method = RequestMethod.GET)
       public ModelAndView listEmployees() { 
              Map<String, Object> model = new HashMap<String, Object>();
              model.put("employees",  prepareListofBean(employeeService.listEmployeess()));
              return new ModelAndView("employeesList", model);
       }

       @RequestMapping(value = "/delete", method = RequestMethod.GET)
       public ModelAndView deleteEmployee(@RequestParam("id") String id) {
              Employee emp =  new Employee();
              emp.setEmpId(Integer.parseInt(id));
              employeeService.deleteEmployee(emp);
              return new ModelAndView("redirect:/list.html");
       }
 
       private Employee prepareModel(EmployeeBean employeeBean, String id){
              Employee employee = new Employee();
              employee.setEmpAddress(employeeBean.getEmpAddress());
              employee.setEmpAge(employeeBean.getEmpAge());
              employee.setEmpName(employeeBean.getEmpName());
              employee.setSalary(employeeBean.getSalary());
              if (id != null && !id.isEmpty()) {
                    employee.setEmpId(Integer.parseInt(id));
              } else {
                    employee.setEmpId(employeeBean.getEmpId());
              }
              return employee;
       }

       private List<EmployeeBean> prepareListofBean(List<Employee> employees){
              List<EmployeeBean> beans = null;
              if(employees != null && !employees.isEmpty()){
                    beans = new ArrayList<EmployeeBean>();
                    EmployeeBean bean = null;
                    for(Employee employee : employees){
                          bean = new EmployeeBean();
                          bean.setEmpName(employee.getEmpName());
                          bean.setEmpId(employee.getEmpId());
                          bean.setEmpAddress(employee.getEmpAddress());
                          bean.setSalary(employee.getSalary());
                          bean.setEmpAge(employee.getEmpAge());
                          beans.add(bean);
                     }
               }
               return beans;
       }
}



Spring Bean Configuration (appln-servlet.xml)
         Next create one xml file under WEB-INF folder, give same file name whatever in the web.xml.
This configuration file config the bean and view using some tags. The appln-servlet.xml file is as follows.

appln-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:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

 <context:property-placeholder location="classpath:resources/database.properties" />
 <context:component-scan base-package="com.adnblog" />

 <tx:annotation-driven transaction-manager="hibernateTransactionManager"/>

 <bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${database.driver}" />
      <property name="url" value="${database.url}" />
      <property name="username" value="${database.user}" />
      <property name="password" value="${database.password}" />
 </bean>

 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <property name="annotatedClasses">
         <list>
             <value>com.adnblog.model.Employee</value>
         </list>
      </property>
      <property name="hibernateProperties">
          <props>
              <prop key="hibernate.dialect">${hibernate.dialect}</prop>
              <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
              <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>    
         </props>
     </property>
 </bean>

 <bean id="hibernateTransactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
           <property name="sessionFactory" ref="sessionFactory" />
 </bean>
 
 <bean id="jspViewResolver"
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
               value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
 </bean>
</beans>



View(Jsp page): - 
         I have created two JSP here, addEmployee.jsp and employeeList.jsp. The addEmployee.jsp is using for adding and editing the employee details, employeeList.jsp is for displaying the employee list and delete the particular employee from the list.
created under pages folder of WEB-INF,   

addEmployee.jsp


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  <c:set var="addOrEdit" value="Add" />
  <c:set var="submit" value="Submit"/>
  <c:if test="${employees.empId != null}">
   <c:set var="addOrEdit" value="Edit" />
   <c:set var="submit" value="Update"/>
  </c:if>
  <title>Spring MVC Add/Edit Operation</title>
 </head>
 <body>
  <h2>${addOrEdit} Employee Data</h2>
  <form:form method="POST" action="/WebAppln/save.html?id=${employees.empId}" commandName="command">
      <table>
       <tr>
           <td><form:label path="empId">Employee ID:</form:label></td>
           <td><c:out value="${employees.empId}"/>
           <form:hidden path="empId" /></td>
       </tr>
       <tr>
           <td><form:label path="empName">Employee Name:</form:label></td>
           <td><form:input path="empName" value="${employees.empName}"/></td>
       </tr>
       <tr>
           <td><form:label path="empAge">Employee Age:</form:label></td>
           <td><form:input path="empAge" value="${employees.empAge}"/></td>
       </tr>
       <tr>
           <td><form:label path="salary">Employee Salary:</form:label></td>
           <td><form:input path="salary" value="${employees.salary}"/></td>
       </tr>
       
       <tr>
           <td><form:label path="empAddress">Employee Address:</form:label></td>
                    <td><form:input path="empAddress" value="${employees.empAddress}"/></td>
       </tr>
       <tr><td></td>
         <td colspan="2"><input type="submit" value="${submit}"/>&nbsp; &nbsp; &nbsp;<b><a href="/WebAppln/list.html" >List Of Employee</a></b></td>
        </tr>
   </table> 
  </form:form>
 </body>
</html>

employeeList.jsp
 
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>All Employees</title>
<style>
table, th, td {
    border: 1px solid black;
    border-collapse: collapse;
}
th, td {
    padding: 5px;
    text-align: left;
}
</style>
</head>
<body>
    <h1>List Employees</h1>
    <c:if test="${empty employees}">
       <h3>No Records found!</h3>
   </c:if>

    <c:if test="${!empty employees}">
 <table align="left" width="100%">
  <tr>
   <th>Employee ID</th>
   <th>Employee Name</th>
   <th>Employee Age</th>
   <th>Employee Salary</th>
   <th>Employee Address</th> 
                        <th></th>
                        <th></th>
  </tr>

  <c:forEach items="${employees}" var="employee">
   <tr>
    <td><c:out value="${employee.empId}"/></td>
    <td><c:out value="${employee.empName}"/></td>
    <td><c:out value="${employee.empAge}"/></td>
    <td><c:out value="${employee.salary}"/></td>
    <td><c:out value="${employee.empAddress}"/></td> 
                                <td><b><a href="/WebAppln/edit.html?id=${employee.empId}">Edit</a></b></td>
                                <td><b><a href="/WebAppln/delete.html?id=${employee.empId}">Delete</a></b></td>
   </tr>
  </c:forEach>
 </table><br/>
</c:if>
<table style="border: none;">
 <tr>
  <td style="padding : none; border: none;"><h3><a href="/WebAppln/add.html">Add More Employee</a></h3></td>
 </tr>
</table>
</body>
</html>



Running the application using Tomcat Server or any Server:--
        If you run the given application without spcifying the URL, it will execute the welcome file i.e add.html so by default add employee will call.



List of Employee : -


Edit screen:--

 Thank you for visiting blog...



Related post :
Spring Annotations
Spring MVC workflow with example  
What is dependency Injection in Spring ? give me types and advantages with examples  
What are different Spring Bean Scopes?
What is Autowiring in Spring ? Explain Autowiring modes and limitations with examples
Spring @Qualifier Annotation with example
Spring Configuration Metadata (XML, Annotation and Java)

1 comment:

  1. Sir,
    EmployeeBean.java is not available in this tutorial

    ReplyDelete