Wednesday, 9 April 2014

Spring Framework - PART - III - Spring with Hibernate

In this discussion i'll demonstrate an application by using spring and hibernate . In which spring as a front end technology , hibernate as a backend ORM technology and MS-SQL server for database connectivity.

Our main goal is to create an user management application in which :-

  • we can add user.
  • we can delete user.
  • Listing of users.
In this application i'll use layered architecture , dao layer that will interact with database. Next is service layer , above that there will be controller and at the top ,  there will be jsp.

Table of contents :- 
Entity class - Hibernate domain class
Create Table
Create Project
Add dependency into pom.xml
Configure dispatcher servlet
The Data Access Layer
The Service Layer
The Controller
JSP

Getting started :-
Lets start with coding of user management application :-

Entity class - Hibernate domain class :-  
First of all , we are creating a hibernate POJO class , that is used to store user information and also linked to database table user  as :-

package com.mycompany.app.user.form;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="user")
public class user {

@Id
@Column(name = "id")
@GeneratedValue
private Integer id;

@Column(name = "firstName")
private String firstname;

@Column(name = "lastName")
private String lastname;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getFirstname() {
return firstname;
}

public void setFirstname(String firstname) {
this.firstname = firstname;
}

public String getLastname() {
return lastname;
}

public void setLastname(String lastname) {
this.lastname = lastname;
}
}

Create Table :-
  • Create table in database :-
CREATE TABLE user
(
     id          INT PRIMARY KEY AUTO_INCREMENT,
     firstname   VARCHAR(30),
     lastname    VARCHAR(30),
  
);

Create Project :- 
  • Next step is to create project using maven command :-


mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
  • To convert maven project to support eclipse IDE , issue the command :-

mvn eclipse:eclipse

  • Now Import the project into eclipse and make the controller , dao , service and jsp layer as :-
                                      
       
Add dependency into pom.xml  :-                                                                                                                                                   
  • Now add dependency related to spring and hibernate  into pom.xml as :-
<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.mycompany.app</groupId>
  <artifactId>springHibernate</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
<properties>
     <org.springframework.version>3.0.2.RELEASE</org.springframework.version>
 <jpa-api-version>2.0-cr-1</jpa-api-version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <org.hibernate-version>3.5.6-Final</org.hibernate-version>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
<configuration>
<!-- Directory for Web application-->
<webappDirectory>webapp</webappDirectory>
<webResources></webResources>
</configuration>
</plugin>
</plugins>
<finalName>springhibernate</finalName>
</build>
  <name>springHibernate</name>
  <url>http://maven.apache.org</url>
 <dependencies>
   <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</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>
    </dependency>
    <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${org.hibernate-version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${org.hibernate-version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.java-persistence</groupId>
<artifactId>jpa-api</artifactId>
<version>${jpa-api-version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
    <!-- dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.4.2</version>
    </dependency -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
      <version>20030825.184428</version>
    </dependency>
    <dependency>
      <groupId>commons-pool</groupId>
      <artifactId>commons-pool</artifactId>
      <version>20030825.183949</version>
    </dependency>
  </dependencies>
  
</project>

Configure dispatcher servlet  :- 
  • As I stated earlier in spring framework ,First of all request comes to dispatcher servlet , so initially set up dispatcher-servlet xml file :-

<?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">
   <context:annotation-config />
    <context:component-scan base-package="com.mycompany.app.user.controller" />
   <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/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
  <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:messages" />
        <property name="defaultEncoding" value="UTF-8" />
    </bean>
 <!-- DataSource configuration. -->
        
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="com.jnetdirect.jsql.JSQLDriver"
p:url="jdbc:JSQLConnect://localhost:1433/database=sample_database"
p:username="sa" p:password="" />
   <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" p: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">org.hibernate.dialect.SQLServerDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
 <tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>

In above file , I have set up following configurations :-

  • To scan all the controller files :-                                                                           <context:component-scan base-package="com.mycompany.app.user.controller" />
  • jspViewResolver bean – This bean defined view resolver for spring mvc. For this bean we also set prefix as “/WEB-INF/jsp/” and suffix as “.jsp”. Thus spring automatically resolves the JSP from WEB-INF/jsp folder and assigned suffix .jsp to it.
  • messageSource bean – To provide Internationalization to our demo application, we defined bundle resource property file called messages.properties in classpath. 
  • dataSource bean – This is the java datasource used to connect to user manager database. We provide jdbc driver class, username, password etc in configuration.
  • sessionFactory bean – This is Hibernate configuration where we define different hibernate settings. hibernate.cfg.xml is set a config file which contains entity class mappings
  • transactionManager bean – We use hibernate transaction manager to manage the transactions of our user manager application.
Next step is to make dao and its implementation i.e. userDao.java interface and its implementation userDaoImpl.java.

The Data Access Layer :- 

useDao.java :-


package com.mycompany.app.user.dao;

import java.util.List;
import com.mycompany.app.user.form.user;
public interface userDao{
     
    public void addUser(user u1);
    public List<user> listUser();
    public void removeUser(Integer id);
}       

userDaoImpl.java :-

package com.mycompany.app.user.dao;

import java.util.List;
import org.hibernate.SessionFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.mycompany.app.user.form.user;

@Repository
public class userDaoImpl implements userDao {
    @Autowired
    private SessionFactory sessionFactory;

    public void addUser(user u1) {
        sessionFactory.getCurrentSession().save(u1);
    }
    public List<user> listUser() {
        return sessionFactory.getCurrentSession().createQuery("from Contact")
                .list();
    }
    public void removeUser(Integer id) {
    user contact = (user) sessionFactory.getCurrentSession().load(
    user.class, id);
        if (null != contact) {
            sessionFactory.getCurrentSession().delete(contact);
        }
    }


}

The DAO layer has 3 functions :-
addUser()  :- To add the users into database.
listUser() :- For listing aa the users that is saved into database.
removeUser() :- To remove the user based on id.

Next step is to make service interface and its corresponding implementation.

The Service layer :- 


userService.java :-

package com.mycompany.app.user.service;
import java.util.List;
import com.mycompany.app.user.form.user;
public interface userService {
     
    public void addUser(user u1);
    public List<user> listUser();
    public void removeUser(Integer id);
}

userServiceImpl.java :- 

package com.mycompany.app.user.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.mycompany.app.user.dao.userDao;
import com.mycompany.app.user.form.user;
@Service
@Transactional
public abstract  class userServiceImpl implements userService {
  @Autowired
    private userDao userdao;
    public void addUser(user u1) {
    userdao.addUser(u1);
    }
  public List<user> listUser() {
        return userdao.listUser();
    }
    public void removeUser(Integer id) {
    userdao.removeUser(id);
    }
}


  • In above service calls , internally I have called dao functions.
  • with the help of @Autowired  , I have injected the dependency of userDao.
  • As I stated initially , Next step is to make controller file.
The Controller :- 

package com.mycompany.app.user.controller;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.mycompany.app.user.form.user;
import com.mycompany.app.user.service.userService;

@Controller
public class userController {
    @Autowired
    private userService userService;
    @RequestMapping("/index")
    public String listUsers(Map<String, Object> map) {
        map.put("user", new user());
        map.put("userList", userService.listUser());
        return "user";
    }
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addUser(@ModelAttribute("user")
    user user, BindingResult result) {
    userService.addUser(user);
        return "redirect:/index";
    }
    @RequestMapping("/delete/{userId}")
    public String deleteUser(@PathVariable("userId")
    Integer userId) {
    userService.removeUser(userId);
        return "redirect:/index";
    }
}


Defining a controller with @Controller :- 
  • @Controller annotations describes that particular class is playing the role of controller.  and in Spring we do not have to extend any base class controller.
  • In [servlet-name]-servelet.xml file we define a tag to scan the controller as :-                  <context:component-scan base-package="com.mycompany.app.user.controller" />    
  •  So, dispatcher scans controller classes define with @controller annotation and detects for another annotations.
@RequestMapping  :-
  • To map the URLs , we use @RequestMapping annotation . It can be use with handler or particular method.
  • As in above example , @RequestMapping is used in many places . 
  • First usage in listUsers method . It means this method will handle the request that will have URL like :-   localhost:8080/springhibernate/index
  • Second usage in addUser Function . It means this method will handle the request that will have URL like :-   localhost:8080/springhibernate/add
  • Third usage in deleteUser. This method will handle the request that will have URL like :- localhost:8080/sprinhghibernate/delete/12 , where 12 = {userId}
@ModelAttribute :- 

  • In addUser Function we have user @ModelAttribute annotation . and also this method has POST request . During POST request we bind the form data with @ModelAttribute  annotation . It specifies the method arguments that is passed from the Form. 
  • In above example, I have passed the user information that is filled into form .
@PathVariable:-
  • It indicates that the meethod paramater is bound to the URI template variable.
  • In above example, userId will get from the URI : - localhost:8080/springhibernate/delete/12 , here userId =12
Also in above controller file following points to be noted :-
  • First is listusers() function , that is handling the URL having /index and returning hello i.e. hello.jsp form to client .
  • Next two functions are returning "redirect:/index" and as listusers() function is handling /index URL , it means it'll render user.jsp file .
  • All the controller functions internally calling service method and which in turn calling dao functions.


JSP :- 
user.jsp file :-

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>User Manager</title>
</head>
<body>
<h2>User Manager</h2>
 <form:form method="post" action="add.html" commandName="user">
 <table>
    <tr>
        <td>First Name</td>
        <td><form:input path="firstName" /></td> 
    </tr>
    <tr>
        <td>Last Name</td>
        <td><form:input path="lastName" /></td>
    </tr>
  
    <tr>
        <td colspan="2">
            <input type="submit" value="Add User"/>
        </td>
    </tr>
</table>  
</form:form>
<h3>Users</h3>
<c:if  test="${!empty userList}">
<table class="data">
<tr>
    <th>Name</th>
</tr>
<c:forEach items="${userList}" var="user">
    <tr>
        <td>${user.lastName}, ${user.firstName} </td>
        <td><a href="delete/${user.id}">delete</a></td>
    </tr>
</c:forEach>
</table>
</c:if>
</body>
</html>

In JSP file , following points are :-

  • At click of submit , action is add.html , i.e.  /add URL will be hit , and addUser() function will handle this.
  • Next is delete/${user.id} , i.e. deleteUser() function will handle this.
This is all about coding . Now deploy the project , add the war into tomcat and restart tomcat . 
Hit the URL localhost:8080/springhibernate/index. 
user.jsp form will render. 


This is what about spring with hibernate. :)