Wednesday, 26 October 2016

Richardson Maturity Model

Richardson Maturity Model provides step by step way to understand the basic ideas behind RESTful thinking. This is more of tool to understand concepts and not something that should be used in some kind of assessment mechanism for your REST api. A model (developed by Leonard Richardson) that breaks down the principal elements of a REST approach into three steps. These introduce resources, http verbs, and hypermedia controls. Each level is a condition for the next, so to qualify for level 3, the only way for a service is to also support levels 1 and 2.


Level 0
The starting point for the model is using HTTP as a transport system for remote interactions, but without using any of the mechanisms of the web. Essentially what you are doing here is using HTTP as a transport mechanism. It will use only one entry point (URI) and one kind of method (in HTTP, this normally is the POST method). Examples of these are SOAP and XML-RPC.

Level 1 - Resources

This is first step towards becoming more RESTful in the Richardson’s Maturity Model. So now rather than making all our requests to a singular service endpoint, we now start talking to individual resources.
When your API can distinguish between different resources, it might be level 1. This level uses multiple URIs, where every URI is the entry point to a specific resource. Instead of going through http://example.com/employees, you actually distinguish between http://example.com/employee/1234 and http://example.com/employee/6789. Still, this level uses only one single HTTP method like POST.

Level 2 - HTTP Verbs

At Level 2, Don't use a single POST method for all, but make use of GET when you are requesting resources, and use the DELETE method when you want to delete a resources. GET is safe and idempotent operation, that is it doesn't make any changes to the state of any resource. This allows to invoke multiple GET safely in any order and still get the same results each time. An important consequence of this is that it allows any participant in the routing of requests to use caching. HTTP includes various measures to support caching, which can be used by all participants in the communication.
The important part of response is the use of an HTTP response code to indicate something has gone wrong. Don't use 200 (OK) code when something went wrong for instance. Rather than using a return code of 200 but including an error response, at level 2 we explicitly use some kind of error response code. It's up to the api designer to decide what codes to use, but there should be a non-2xx response if an error crops up. Level 2 introduces using HTTP verbs and HTTP response codes.

Level 3 - Hypermedia Controls

The final level introduces something that you often hear referred to under the acronym of HATEOAS (Hypertext As The Engine Of Application State). The point of hypermedia controls is that they tell us what we can do next, and the URI of the resource we need to manipulate to do it. One obvious benefit of hypermedia controls is that it allows the server to change its URI scheme without breaking clients. As long as clients look up the linkrels URI then the provider can juggle all URIs except the initial entry points.

A additional benefit is that it helps client developers explore the protocol. The links give client developers a hint as to what may be possible next. Similarly it allows the server team to advertise new capabilities by putting new links in the responses. If the client developers are keeping an eye out for unknown links these links can be a trigger for further exploration.

3. Hibernate Spring Properties File Configuration

In previous tutorials, we covered how to integrate Spring with Hibernate and perform few of very basic operations for CRUD. We created DataSource and SessionFactory using 'org.springframework.jdbc.datasource.DriverManagerDataSource' and 'org.springframework.orm.hibernate4.LocalSessionFactoryBean' respectively.

However there was issue that all required properties to create these beans were hard coded in Spring config XML file. We do not this hard coding and want to move these values to properties file so we can better manage them.

In this tutorial, we will see how we can do this.

To start with, create properties file with name 'hibernate.properties' in src/main/resources folder.

hibernate.properties

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/rmsystem
jdbc.user=postgres
jdbc.pass=password
 
hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
hibernate.current_session_context_class=thread
hibernate.cache.provider_class=org.hibernate.cache.internal.NoCacheProvider
hibernate.autocommit=false
hibernate.format_sql=true

We moved all properties from Spring.xml file to hibernate.properties file as above.

Now next task is to configure Spring to read this properties file and give keys of property instead of values directly while creating beans. Add below in your spring.xml file to configure properties file in Spring.

<context:property-placeholder location="classpath:hibernate.properties" />

as hibernate.properties file is on classpath (everything we put inside resources folder by default is on classpath) we mentioned location as "classpath:hibernate.properties"

Once that's done, we need to replace all hard coded properties with keys from properties file. We mention this like ${KEY} and spring takes care of replacing those with respective values at Spring context start up.

Spring.xml

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?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:jee="http://www.springframework.org/schema/jee" xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">

 <context:component-scan base-package="in.blogspot.ashish4java.employeesystem" />

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

 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="packagesToScan" value="in.blogspot.ashish4java.employeesystem.model"></property>
  <property name="dataSource" ref="myDataSource" />
  <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>
    <prop key="current_session_context_class">${hibernate.current_session_context_class}</prop>
    <prop key="cache.provider_class">${hibernate.cache.provider_class}</prop>
    <prop key="hibernate.autocommit">${hibernate.autocommit}</prop>
    <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
   </props>
  </property>
 </bean>

 <context:property-placeholder location="classpath:hibernate.properties" />

</beans>

Run MainClient class and you will see property values are picked up properly by Spring and there shouldn't be any difference during runtime.

Another issue which you must have noticed with using DriverManagerDataSource is you need to provide driver class name, database url along with username/password. Its not idea to store store password in properties file also as it has security risk and also issue like what if database password changes. Do we need to redeploy complete application again with changed password?

SO this DriverManagerDataSource is not very convenient to use. Spring provides option of using datasource configured in your application server using JNDI lookup with help of 'org.springframework.jndi.JndiObjectFactoryBean'.

We will see how to do this in future tutorial.

Monday, 24 October 2016

2. Hibernate Spring More Operations

In previous tutorial, we have seen how to integrate hibernate with Spring and perform few of operations like creating entity and getting particular entity.

Now, we will extend that tutorial and will look how to perform more operations like fetching all entities , fetching all matching entities from database.

First, we need to add these new methods in DAO interface as below,
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package in.blogspot.ashish4java.employeesystem.dao;

import java.util.List;

import in.blogspot.ashish4java.employeesystem.model.Employee;

public interface EmployeeDao {

 void createEmployee(Employee emp);

 void updateEmployee(Employee emp);

 void deleteEmployee(Employee emp);

 Employee getEmployee(int employeeId);

 List<Employee> findAllEmployees();

 List<Employee> findAllEmployeesByDesignation(String designation);

}

Implement both these methods one by one.
Implementation of findAllEmployees() method will be like below,
1
2
3
4
5
6
7
 @SuppressWarnings("unchecked")
 @Override
 public List<Employee> findAllEmployees() {
  Session session = getsession();
  Criteria criteria = session.createCriteria(Employee.class);
  return (List<Employee>) criteria.list();
 }

We have used hibernate Criteria object to fetch all records from database table. We did something similar in previous tutorial as well.

Implementation of findAllEmployeesByDesignation(String designation) method will be like below,
1
2
3
4
5
6
7
8
 @SuppressWarnings("unchecked")
 @Override
 public List<Employee> findAllEmployeesByDesignation(String designation) {
  Session session = getsession();
  Query query = session.createQuery("from Employee where designation = :designation");
  query.setString("designation", designation);
  return query.list();
 }

In this implementation, we have used Hibernate Query Language (HQL) by creating Query object and passing required parameter in where clause. HQL is very similar to SQL however it has benefit that HQL is database independent so even if database type changes, there won't be much changes needed in DAO classes. Hibernate uses dialect defined to convert HQL to database specific query.

Now, let's update Service interface and implementation class for calling these operations.

EmployeeService.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package in.blogspot.ashish4java.employeesystem.service;

import java.util.List;

import in.blogspot.ashish4java.employeesystem.model.Employee;

public interface EmployeeService {

 void createEmployee(Employee emp);

 void updateEmployee(Employee emp);

 void deleteEmployee(Employee emp);

 Employee getEmployee(int employeeId);

 List<Employee> findAllEmployees();

 List<Employee> findAllEmployeesByDesignation(String designation);

}

EmployeeServiceImpl.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package in.blogspot.ashish4java.employeesystem.service;

import java.util.List;

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

import in.blogspot.ashish4java.employeesystem.dao.EmployeeDao;
import in.blogspot.ashish4java.employeesystem.model.Employee;

@Service ("empService")
public class EmployeeServiceImpl implements EmployeeService {

 @Autowired
 EmployeeDao employeeDao;

 @Override
 public void createEmployee(Employee emp) {
  employeeDao.createEmployee(emp);

 }

 @Override
 public void updateEmployee(Employee emp) {
  employeeDao.updateEmployee(emp);
 }

 @Override
 public void deleteEmployee(Employee emp) {
  employeeDao.deleteEmployee(emp);
 }

 @Override
 public Employee getEmployee(int employeeId) {
  return employeeDao.getEmployee(employeeId);
 }

 @Override
 public List<Employee> findAllEmployees() {
  return employeeDao.findAllEmployees();
 }

 @Override
 public List<Employee> findAllEmployeesByDesignation(String designation) {
  return employeeDao.findAllEmployeesByDesignation(designation);
 }

}

Updated client to demonstrate this is as below,

MainClient.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package in.blogspot.ashish4java.employeesystem.client;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import in.blogspot.ashish4java.employeesystem.model.Employee;
import in.blogspot.ashish4java.employeesystem.service.EmployeeService;
import in.blogspot.ashish4java.employeesystem.utils.EmployeeHelper;

public class MainClient {

 public static void main(String[] args) {
  ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
  EmployeeHelper empHelper = (EmployeeHelper) context.getBean("empHelper");

  EmployeeService service = (EmployeeService) context.getBean("empService");

  for (int i = 1; i < 4; i++) {
   // Cretae Employee
   service.createEmployee(empHelper.CreateEmployeeOnRequest());
  }

  // Get All Employees Details
  List<Employee> employeesList = service.findAllEmployees();

  System.out.println();
  for (Employee employee : employeesList) {
   System.out.println(employee);
  }

  // Get All Employees with designation
  List<Employee> emplList = service.findAllEmployeesByDesignation("Full Stack Java developer");

  System.out.println();
  for (Employee employee : emplList) {
   System.out.println(employee);
  }
  context.close();
 }
}

Output

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
INFO: HHH000227: Running hbm2ddl schema export
Hibernate: 
    drop table EMPLOYEE cascade
Hibernate: 
    drop sequence hibernate_sequence
Hibernate: 
    create table EMPLOYEE (
        employeeId int4 not null,
        designation varchar(255),
        firstName varchar(255),
        joiningDate timestamp,
        lastName varchar(255),
        leavingDate timestamp,
        primary key (employeeId)
    )
Hibernate: 
    create sequence hibernate_sequence
Oct 24, 2016 10:49:08 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: 
    select
        nextval ('hibernate_sequence')
Hibernate: 
    insert 
    into
        EMPLOYEE
        (designation, firstName, joiningDate, lastName, leavingDate, employeeId) 
    values
        (?, ?, ?, ?, ?, ?)
Hibernate: 
    select
        nextval ('hibernate_sequence')
Hibernate: 
    insert 
    into
        EMPLOYEE
        (designation, firstName, joiningDate, lastName, leavingDate, employeeId) 
    values
        (?, ?, ?, ?, ?, ?)
Hibernate: 
    select
        nextval ('hibernate_sequence')
Hibernate: 
    insert 
    into
        EMPLOYEE
        (designation, firstName, joiningDate, lastName, leavingDate, employeeId) 
    values
        (?, ?, ?, ?, ?, ?)
Hibernate: 
    select
        this_.employeeId as employee1_0_0_,
        this_.designation as designat2_0_0_,
        this_.firstName as firstNam3_0_0_,
        this_.joiningDate as joiningD4_0_0_,
        this_.lastName as lastName5_0_0_,
        this_.leavingDate as leavingD6_0_0_ 
    from
        EMPLOYEE this_

Employee [firstName=ABC98, lastName=XYZ18, employeeId=1, joiningDate=null, leavingDate=null, designation=Full Stack Java developer]
Employee [firstName=ABC73, lastName=XYZ75, employeeId=2, joiningDate=null, leavingDate=null, designation=Full Stack Java developer]
Employee [firstName=ABC13, lastName=XYZ61, employeeId=3, joiningDate=null, leavingDate=null, designation=Full Stack Java developer]
Hibernate: 
    select
        employee0_.employeeId as employee1_0_,
        employee0_.designation as designat2_0_,
        employee0_.firstName as firstNam3_0_,
        employee0_.joiningDate as joiningD4_0_,
        employee0_.lastName as lastName5_0_,
        employee0_.leavingDate as leavingD6_0_ 
    from
        EMPLOYEE employee0_ 
    where
        employee0_.designation=?

Employee [firstName=ABC98, lastName=XYZ18, employeeId=1, joiningDate=null, leavingDate=null, designation=Full Stack Java developer]
Employee [firstName=ABC73, lastName=XYZ75, employeeId=2, joiningDate=null, leavingDate=null, designation=Full Stack Java developer]
Employee [firstName=ABC13, lastName=XYZ61, employeeId=3, joiningDate=null, leavingDate=null, designation=Full Stack Java developer]
Oct 24, 2016 10:49:10 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@133ddba: startup date [Mon Oct 24 22:49:04 IST 2016]; root of context hierarchy

This is end of this tutorial. In next couple of tutorials, we will address two important issues where all database properties were hard coded in Spring context XML file to create SessionFactory and DataSource. We will see how we can move those to properties file. Another issue was, to manage transaction, we have to open session, begin transaction and then based on successful operation or not, either commit or rollback transaction. There is lot of boilerplate code in it. We will see how can we get rid of that using Spring managed transaction.

Thursday, 20 October 2016

1. Hibernate Spring Integration Example

Hibernate is most popular ORM framework and Spring is widely used J2EE framework so combination of Spring with Hibernate is used lot in many enterprise level applications. Hibernate is JPA provider with lot of addition of added functionalities.

In this series of tutorials, we will be exploring different functionalities of Hibernate and will see how Spring makes it more easier to configure and use Hibernate.

Artifacts used in these tutorials are,

Spring - 4.3.3.RELEASE
Hibernate - 4.3.11.Final

First look at final project structure. We will look at each of these one by one.


POM.xml for dependencies is as below,

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 <properties>
  <springframework.version>4.3.3.RELEASE</springframework.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${springframework.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</artifactId>
   <version>${springframework.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-jdbc</artifactId>
   <version>${springframework.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-orm</artifactId>
   <version>${springframework.version}</version>
  </dependency>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>4.3.11.Final</version>
  </dependency>
  <dependency>
   <groupId>postgresql</groupId>
   <artifactId>postgresql</artifactId>
   <version>9.1-901-1.jdbc4</version>
  </dependency>
 </dependencies>

Dependency for PostgreSQL is also added as we will be using PostgreSQL database for this tutorial.

Now, first we will create entity class 'Employee' using JPA annotations as hibernate provides JPA implementation.

Employee.java
1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
package in.blogspot.ashish4java.employeesystem.model;

import java.io.Serializable;
import java.util.Date;

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

@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable {

 /**
  * 
  */
 private static final long serialVersionUID = -7778913816135373156L;
 private String firstName;
 private String lastName;

 @Id
 @GeneratedValue
 private int employeeId;

 private Date joiningDate;
 private Date leavingDate;

 private String designation;

 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 int getEmployeeId() {
  return employeeId;
 }

 public void setEmployeeId(int employeeId) {
  this.employeeId = employeeId;
 }

 public Date getJoiningDate() {
  return joiningDate;
 }

 public void setJoiningDate(Date joiningDate) {
  this.joiningDate = joiningDate;
 }

 public Date getLeavingDate() {
  return leavingDate;
 }

 public void setLeavingDate(Date leavingDate) {
  this.leavingDate = leavingDate;
 }

 public String getDesignation() {
  return designation;
 }

 public void setDesignation(String designation) {
  this.designation = designation;
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + employeeId;
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Employee other = (Employee) obj;
  if (employeeId != other.employeeId)
   return false;
  return true;
 }

 @Override
 public String toString() {
  return "Employee [firstName=" + firstName + ", lastName=" + lastName + ", employeeId=" + employeeId
    + ", joiningDate=" + joiningDate + ", leavingDate=" + leavingDate + ", designation=" + designation
    + "]";
 }

}

Make Employee entity serializable. EmployeeId field is primary key and value for that will be automatically generated by Hibernate.

DAO Classes
Next, we will create DAO classes for creating and fetching this entity from database. Create, Delete, Update and Get - these will be main operations in DAO class which we will implement.

Let's create interface first for DAO class to define this contract.

EmployeeDao.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package in.blogspot.ashish4java.employeesystem.dao;

import in.blogspot.ashish4java.employeesystem.model.Employee;

public interface EmployeeDao {

 void createEmployee(Employee emp);

 void updateEmployee(Employee emp);

 void deleteEmployee(Employee emp);

 Employee getEmployee(int employeeId);

}

Create abstract DAO class and provide implementation of few of common methods,

AbstractDao.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package in.blogspot.ashish4java.employeesystem.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class AbstractDao {

 @Autowired
 SessionFactory sessionFactory;

 protected Session getsession() {
  return sessionFactory.openSession();
 }

 public void createEntity(Object entity) {
  Session session = getsession();
  session.beginTransaction();
  session.save(entity);
  session.getTransaction().commit();
 }

 public void updateEntity(Object entity) {
  Session session = getsession();
  session.beginTransaction();
  session.update(entity);
  session.getTransaction().commit();
 }

 public void deleteEntity(Object entity) {
  Session session = getsession();
  session.beginTransaction();
  session.delete(entity);
  session.getTransaction().commit();
 }

}

Note: SessionFactoy will be autowired by Spring and then Session object is given by this factory using openSession() method which opens new session everytime. This session needs to be closed everytime once transaction is over as session is not thread safe. If you note, there is lot of boilerplate code in these DAO methods like getting session, beginning transaction, performing operation and then committing transaction. In one of future tutorial, we will see how to get rid of this using Spring provided transaction management.

Let's implement remaining method from EmployeeDao interface

EmployeeDaoImpl.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package in.blogspot.ashish4java.employeesystem.dao;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import in.blogspot.ashish4java.employeesystem.model.Employee;

@Repository
public class EmployeeDaoImpl extends AbstractDao implements EmployeeDao {

 @Override
 public void createEmployee(Employee emp) {
  createEntity(emp);
 }

 @Override
 public void updateEmployee(Employee emp) {
  updateEntity(emp);
 }

 @Override
 public void deleteEmployee(Employee emp) {
  deleteEntity(emp);
 }

 @Override
 public Employee getEmployee(int employeeId) {
  Session session = getsession();
  Criteria criteria = session.createCriteria(Employee.class).add(Restrictions.eq("employeeId", employeeId));
  return (Employee) criteria.uniqueResult();
 }

}

Notice we have used Criteria then putting Restriction on employeeId to fetch particular employee from table. There are different ways to implement this in hibernate and this is one of them.

Service Class implementation

EmployeeService.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package in.blogspot.ashish4java.employeesystem.service;

import in.blogspot.ashish4java.employeesystem.model.Employee;

public interface EmployeeService {

 void createEmployee(Employee emp);

 void updateEmployee(Employee emp);

 void deleteEmployee(Employee emp);

 Employee getEmployee(int employeeId);

}

EmployeeServiceImple.java

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package in.blogspot.ashish4java.employeesystem.service;

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

import in.blogspot.ashish4java.employeesystem.dao.EmployeeDao;
import in.blogspot.ashish4java.employeesystem.model.Employee;

@Service ("empService")
public class EmployeeServiceImpl implements EmployeeService {

 @Autowired
 EmployeeDao employeeDao;

 @Override
 public void createEmployee(Employee emp) {
  employeeDao.createEmployee(emp);

 }

 @Override
 public void updateEmployee(Employee emp) {
  employeeDao.updateEmployee(emp);
 }

 @Override
 public void deleteEmployee(Employee emp) {
  employeeDao.deleteEmployee(emp);
 }

 @Override
 public Employee getEmployee(int employeeId) {
  return employeeDao.getEmployee(employeeId);
 }
}

Spring Bean Configuration XML

Spring.xml

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?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:jee="http://www.springframework.org/schema/jee" xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
  http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">

 <context:component-scan base-package="in.blogspot.ashish4java.employeesystem" />

 <bean id="myDataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="org.postgresql.Driver" />
  <property name="url" value="jdbc:postgresql://localhost:5432/rmsystem" />
  <property name="username" value="postgres" />
  <property name="password" value="password" />
 </bean>

 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="packagesToScan" value="in.blogspot.ashish4java.employeesystem.model"></property>
  <property name="dataSource" ref="myDataSource" />
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.hbm2ddl.auto">create</prop>
    <prop key="current_session_context_class">thread</prop>
    <prop key="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</prop>
    <prop key="hibernate.autocommit">false</prop>
    <prop key="hibernate.format_sql">true</prop>
   </props>
  </property>
 </bean>
</beans>

We have created datasource first and then passed that datasource to create SessionFactory. Spring provides implementation of SessionFactory with "org.springframework.orm.hibernate4.LocalSessionFactoryBean"

Now, remaining part is to implement client to demonstrate this complete example.

I have created one helper class which will give set Employee object which needs to be persisted to database. This utility class is not necessary and can be ignored.

EmployeeHelper.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package in.blogspot.ashish4java.employeesystem.utils;

import java.util.Random;

import org.springframework.stereotype.Component;

import in.blogspot.ashish4java.employeesystem.model.Employee;

@Component("empHelper")
public class EmployeeHelper {

 private static final String designation = "Full Stack Java developer";

 public Employee CreateEmployeeOnRequest() {
  Random r = new Random();
  Employee emp = new Employee();
  emp.setFirstName("ABC" + r.nextInt(100));
  emp.setLastName("XYZ" + r.nextInt(100));
  emp.setDesignation(designation);
  return emp;
 }

}

MainClient.java
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package in.blogspot.ashish4java.employeesystem.client;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import in.blogspot.ashish4java.employeesystem.model.Employee;
import in.blogspot.ashish4java.employeesystem.service.EmployeeService;
import in.blogspot.ashish4java.employeesystem.utils.EmployeeHelper;

public class MainClient {

 public static void main(String[] args) {
  ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
  EmployeeHelper empHelper = (EmployeeHelper) context.getBean("empHelper");
  Employee emp = empHelper.CreateEmployeeOnRequest();

  EmployeeService service = (EmployeeService) context.getBean("empService");

  // Cretae Employee
  service.createEmployee(emp);

  // Get Employee Details for ID = 1
  Employee employee = service.getEmployee(1);

  System.out.println();
  System.out.println(employee);

  context.close();

 }

}

Make sure, PostgrSQL database is up and running. Now, let's execute this client and see the output.

Output
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
INFO: HHH000227: Running hbm2ddl schema export
Hibernate: 
    drop table EMPLOYEE cascade
Hibernate: 
    drop sequence hibernate_sequence
Hibernate: 
    create table EMPLOYEE (
        employeeId int4 not null,
        designation varchar(255),
        firstName varchar(255),
        joiningDate timestamp,
        lastName varchar(255),
        leavingDate timestamp,
        primary key (employeeId)
    )
Hibernate: 
    create sequence hibernate_sequence
Oct 20, 2016 9:46:15 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: 
    select
        nextval ('hibernate_sequence')
Hibernate: 
    insert 
    into
        EMPLOYEE
        (designation, firstName, joiningDate, lastName, leavingDate, employeeId) 
    values
        (?, ?, ?, ?, ?, ?)
Hibernate: 
    select
        this_.employeeId as employee1_0_0_,
        this_.designation as designat2_0_0_,
        this_.firstName as firstNam3_0_0_,
        this_.joiningDate as joiningD4_0_0_,
        this_.lastName as lastName5_0_0_,
        this_.leavingDate as leavingD6_0_0_ 
    from
        EMPLOYEE this_ 
    where
        this_.employeeId=?

Employee [firstName=ABC66, lastName=XYZ53, employeeId=1, joiningDate=null, leavingDate=null, designation=Full Stack Java developer]
Oct 20, 2016 9:46:16 AM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@133ddba: startup date [Thu Oct 20 09:46:07 IST 2016]; root of context hierarchy

Output clearly shows, it has created Employee table first along with sequence for primary key when SessionFactory was created. Then client execution, it inserted one record in that table as we expected and same record was fetched.

In next tutorial, we will see few more operations like how to fetch all employees from table and how to fetch sub set of employees based on where clause.