Spring 4 Restful Web Services With Hibernate 4 Example using Maven


Spring 4 Restful Web Services With Hibernate 4 Example using Maven – Server Application In our previous discussions we came across several Spring related topics. In this particular tutorial we will see how to create Spring Restful Web Services With Hibernate using Maven. We will create and build the project with Maven and hibernate 4 will be used in data layer. 

To get started simply create a simple web application with maven and import it in Eclipse. If you are new to Maven please go through the Link below. 

Now we have a skeleton Maven project imported to eclipse, lets add all required Java and Configuration files to it as shown in the rest part of the tutorial. 

Database Setup
Here us MySql script to create a simple database and table structure to be used in our application, simply paste the script in query editor and run to make a DB skeleton.
/*!40101 SET @[email protected]@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET FOREIGN_KEY_CHECKS=0 */;

-- Dumping database structure for employee_db
CREATE DATABASE IF NOT EXISTS `employee_db` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `employee_db`;

-- Dumping structure for table employee_db.employee
CREATE TABLE IF NOT EXISTS `employee` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) DEFAULT NULL,
`last_name` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`phone` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

-- Dumping data for table employee_db.employee: ~1 rows (approximately)
/*!40000 ALTER TABLE `employee` DISABLE KEYS */;
INSERT INTO `employee` (`id`, `first_name`, `last_name`, `email`, `phone`) VALUES
(2, 'Hoston', 'lindey', '[email protected]', '90908989899');
/*!40000 ALTER TABLE `employee` ENABLE KEYS */;
/*!40014 SET FOREIGN_KEY_CHECKS=1 */;
/*!40101 SET [email protected]_CHARACTER_SET_CLIENT */;

Dependencies required to make Spring Restful Web Services with Hibernate

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.developerfirm.sample</groupId>
<artifactId>SpringRestCrud</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringRestCrud Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.0.5.RELEASE</spring.version>
<hibernate.version>4.3.5.Final</hibernate.version>
<log4j.version>1.2.17</log4j.version>
<jdk.version>1.7</jdk.version>
<context.path>SpringRestCrud</context.path>
</properties>
<build>
<finalName>${pom.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.10</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
</project>

\src\main\webapp\WEB-INF\web.xml
We need to make an Spring entry to web.xml, this will tell the container that all upcoming requests will be served by Spring Framework itself as per the configuration.
<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_2_5.xsd"
version="2.5">
<display-name>Sample Spring Maven Project</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

</web-app>
\src\main\webapp\WEB-INF\spring-config.xml
This is simple spring configuration file, we have added entry for base-package her to search and find Controller classes with annotations. We defined two beans here for Service and Dao layer that we will see in details shortly. Rest is hibernate configurations and a datasource bean to connect with database.  
<?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:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<context:component-scan base-package="com.developerfirm.controller" />
<mvc:annotation-driven />

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/employee_db" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.developerfirm.model.Employee</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<bean id="dataDao" class="com.developerfirm.dao.DataDaoImpl"></bean>
<bean id="dataServices" class="com.developerfirm.services.DataServicesImpl"></bean>
</beans>
\src\main\java\com\developerfirm\controller\RestController.java
This is simple Spring MVC controller with annotations, we have added all general purpose methods here those method will accept a rest request in Json form and will return a JSON response. The methods are self explanatory we have used @Controller annotation to point incoming requests to this class, and @RequestMapping annotation to point incoming requests to appropriate Methods. @RequestBody annotation is used to accept data with request in Json form and @ResponseBody is used to return JSON as response to incoming request.
package com.developerfirm.controller;

import java.util.List;

import org.apache.log4j.Logger;
import com.developerfirm.model.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.developerfirm.model.Employee;
import com.developerfirm.services.DataServices;

@Controller
@RequestMapping("/employee")
public class RestController {

@Autowired
DataServices dataServices;

static final Logger logger = Logger.getLogger(RestController.class);

/* Submit form in Spring Restful Services */
@RequestMapping(value = "/create", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
Status addEmployee(@RequestBody Employee employee) {
try {
dataServices.addEntity(employee);
return new Status(1, "Employee added Successfully !");
} catch (Exception e) {
// e.printStackTrace();
return new Status(0, e.toString());
}

}

/* Ger a single objct in Json form in Spring Rest Services */
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public @ResponseBody
Employee getEmployee(@PathVariable("id") long id) {
Employee employee = null;
try {
employee = dataServices.getEntityById(id);

} catch (Exception e) {
e.printStackTrace();
}
return employee;
}

/* Getting List of objects in Json format in Spring Restful Services */
@RequestMapping(value = "/list", method = RequestMethod.GET)
public @ResponseBody
List getEmployee() {

List employeeList = null;
try {
employeeList = dataServices.getEntityList();

} catch (Exception e) {
e.printStackTrace();
}

return employeeList;
}

/* Delete an object from DB in Spring Restful Services */
@RequestMapping(value = "delete/{id}", method = RequestMethod.GET)
public @ResponseBody
Status deleteEmployee(@PathVariable("id") long id) {

try {
dataServices.deleteEntity(id);
return new Status(1, "Employee deleted Successfully !");
} catch (Exception e) {
return new Status(0, e.toString());
}

}
}

Model Classes

\SpringRestCrud\src\main\java\com\developerfirm\model\Employee.java
This is simple POJO to represent Employee entity in our application, we will be dealing with Employee entity to save, retrieve and delete data using Spring Restful Web Services. We have annotated the class with Hibernate annotations to make hibernate aware of the entity.
package com.developerfirm.model;

import java.io.Serializable;

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

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@Entity
@Table(name = "employee")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Employee implements Serializable {

private static final long serialVersionUID = 1L;

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

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

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

@Column(name = "email")
private String email;

@Column(name = "phone")
private String phone;

public long getId() {
return id;
}

public void setId(long 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;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPhone() {
return phone;
}

public void setPhone(String phone) {
this.phone = phone;
}
}
Don’t forget to add @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) annotation to class, this is used to resolve Hibernate and Json conflict. 

\src\main\java\com\developerfirm\model\Status.java
This is another POJO to represent conditional Status and Error messages in form of Json, this comes handy in case of sending status response to requests if needed.
package com.developerfirm.model;

public class Status {

private int code;
private String message;

public Status() {
}

public Status(int code, String message) {
this.code = code;
this.message = message;
}

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}

Data layer with spring and hibernate

Below are simple Service and Dao classes and Interfaces to make a two tier data layer between Spring and Hibernate. 

\src\main\java\com\developerfirm\dao\DataDao.java
package com.developerfirm.dao;

import java.util.List;

import com.developerfirm.model.Employee;

public interface DataDao {

public boolean addEntity(Employee employee) throws Exception;
public Employee getEntityById(long id) throws Exception;
public List getEntityList() throws Exception;
public boolean deleteEntity(long id) throws Exception;
}
\src\main\java\com\developerfirm\dao\DataDaoImpl.java
package com.developerfirm.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import com.developerfirm.model.Employee;

public class DataDaoImpl implements DataDao {

@Autowired
SessionFactory sessionFactory;

Session session = null;
Transaction tx = null;

@Override
public boolean addEntity(Employee employee) throws Exception {

session = sessionFactory.openSession();
tx = session.beginTransaction();
session.save(employee);
tx.commit();
session.close();

return false;
}

@Override
public Employee getEntityById(long id) throws Exception {
session = sessionFactory.openSession();
Employee employee = (Employee) session.load(Employee.class,
new Long(id));
tx = session.getTransaction();
session.beginTransaction();
tx.commit();
return employee;
}

@SuppressWarnings("unchecked")
@Override
public List getEntityList() throws Exception {
session = sessionFactory.openSession();
tx = session.beginTransaction();
List employeeList = session.createCriteria(Employee.class)
.list();
tx.commit();
session.close();
return employeeList;
}

@Override
public boolean deleteEntity(long id)
throws Exception {
session = sessionFactory.openSession();
Object o = session.load(Employee.class, id);
tx = session.getTransaction();
session.beginTransaction();
session.delete(o);
tx.commit();
return false;
}

}
\src\main\java\com\develoeprfirm\services\DataServices.java
package com.developerfirm.services;

import java.util.List;

import com.developerfirm.model.Employee;

public interface DataServices {
public boolean addEntity(Employee employee) throws Exception;
public Employee getEntityById(long id) throws Exception;
public List getEntityList() throws Exception;
public boolean deleteEntity(long id) throws Exception;
}
\src\main\java\com\developerfirm\services\DataServicesImpl.java
package com.developerfirm.services;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.developerfirm.dao.DataDao;
import com.developerfirm.model.Employee;

public class DataServicesImpl implements DataServices {

@Autowired
DataDao dataDao;

@Override
public boolean addEntity(Employee employee) throws Exception {
return dataDao.addEntity(employee);
}

@Override
public Employee getEntityById(long id) throws Exception {
return dataDao.getEntityById(id);
}

@Override
public List getEntityList() throws Exception {
return dataDao.getEntityList();
}

@Override
public boolean deleteEntity(long id) throws Exception {
return dataDao.deleteEntity(id);
}
}
In this particular article we came across "Spring 4 Restful Web Services With Hibernate 4 Example using Maven", in our next discussion we will see how to create a Client Application in Spring to consume Spring Restful Services. 
NOTE : In case you want to test the application with some dummy data and without using any client application, you can do that using  Chrome's Postman - REST Client. Make sure to set  content-type: application/json when sending form data in JSON format to the service.