Spring MVC With Hibernate and Postgresql
Spring MVC With Hibernate and Postgresql
Spring MVC With Hibernate and Postgresql
of Contents
Introduction 1.1
Architecture 1.1.1
Graph 1.1.1.1
Dependencies 1.2
PostgreSQL Database Setup 1.3
Structure in Eclipse 1.4
Entity Class 1.5
DAO Layer 1.6
Service Layer 1.7
Presentation Layer 1.8
PhoneContoller 1.9
JSP 1.10
Web Configuration 1.11
servlet-context.xml 1.12
Results 1.13
1
Introduction
Objectives
1) How to integrate Spring MVC with Hibernate using Maven
2
Architecture
Architecture
This architecture clearly explains our demo application. The database will be
accessed by a Data Access layer popularly called as DAO Layer. This layer will
use Hibernate API to interact with database. The DAO layer will be invoked by a
service layer.
3
Graph
4
Dependencies
Dependencies
Let us start by creating a simple web project with maven in Eclipse IDE, now let
me tell how to setup the project in pom.xml, follow are the dependencies required
for our program:
5
Dependencies
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1207.jre7</version>
</dependency>
6
Dependencies
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
7
Dependencies
<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>
8
Dependencies
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.e
clipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.ec
lipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgume
nt>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
9
Dependencies
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>
10
PostgreSQL Database Setup
11
Structure in Eclipse
Structure
Create following packages under src/main/java folder.
4) com.demo.spring.service This package will contain code for service layer for
our Phone application. The service layer will have one PhoneService interface
and its corresponding implementation class
12
Structure in Eclipse
13
Entity Class
Entity Class
First we will create an object or hibernate POJO class to store phone information.
Also this class will be an Entity class and will be linked with Phone table in
database.
Note:
First weve annotated the class with @Entity which tells Hibernate that this
class represents an object that we can persist.
Phone.java
package com.spring.demo.model;
14
Entity Class
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Entity bean with JPA annotations Hibernate provides JPA imple
mentation
*/
@Entity
@Table(name = "PHONE")
public class Phone {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
@Column(name = "review")
private String review;
15
Entity Class
@Override
public String toString() {
return "Phone [id=" + id + ", name=" + name + ", review=
" + review + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Phone other = (Phone) obj;
if (id != other.id)
return false;
return true;
}
16
Entity Class
17
DAO Layer
DAO Layer
The DAO class code PhoneDAOImpl implements the data access interface
PhoneDAO which defines methods such as addPhone(), updatePhone(),
listPhones(), getPhoneById() and removePhone() to access data from database.
PhoneDAO.java
package com.spring.demo.dao;
import java.util.List;
import com.spring.demo.model.Phone;
PhoneDAOImpl.java
package com.spring.demo.dao;
import java.util.List;
18
DAO Layer
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import com.spring.demo.model.Phone;
@Repository
public class PhoneDAOImpl implements PhoneDAO {
@Override
public void addPhone(Phone p) {
Session session = this.sessionFactory.getCurrentSession(
);
session.persist(p);
logger.info("Phone saved successfully, Phone Details=" +
p);
}
@Override
public void updatePhone(Phone p) {
Session session = this.sessionFactory.getCurrentSession(
);
session.update(p);
logger.info("Phone updated successfully, Phone Details="
+ p);
}
@SuppressWarnings("unchecked")
19
DAO Layer
@Override
public List<Phone> listPhones() {
Session session = this.sessionFactory.getCurrentSession(
);
List<Phone> phonesList = session.createQuery("from Phone
").list();
for (Phone p : phonesList) {
logger.info("Phone List::" + p);
}
return phonesList;
}
@Override
public Phone getPhoneById(int id) {
Session session = this.sessionFactory.getCurrentSession(
);
Phone p = (Phone) session.load(Phone.class, new Integer(
id));
logger.info("Phone loaded successfully, Phone details="
+ p);
return p;
}
@Override
public void removePhone(int id) {
Session session = this.sessionFactory.getCurrentSession(
);
Phone p = (Phone) session.load(Phone.class, new Integer(
id));
if (null != p) {
session.delete(p);
}
logger.info("Phone deleted successfully, phone details="
+ p);
}
20
DAO Layer
21
Service Layer
Service Layer
This Service Layer act as a bridge between the DAO (Persistence) layer and the
Presentation (Web) layer. Even in service layer similar to DAO layer we have the
interface and its implementation.
@Service:
@Transactional:
@Autowired*
PhoneService.java
22
Service Layer
package com.spring.demo.service;
import java.util.List;
import com.spring.demo.model.Phone;
PhoneServiceImpl.java
package com.spring.demo.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.spring.demo.dao.PhoneDAO;
import com.spring.demo.model.Phone;
@Service
public class PhoneServiceImpl implements PhoneService {
@Autowired
private PhoneDAO phoneDAO;
@Override
23
Service Layer
@Transactional
public void addPhone(Phone p) {
this.phoneDAO.addPhone(p);
}
@Override
@Transactional
public void updatePhone(Phone p) {
this.phoneDAO.updatePhone(p);
}
@Override
@Transactional
public List<Phone> listPhones() {
return this.phoneDAO.listPhones();
}
@Override
@Transactional
public Phone getPhoneById(int id) {
return this.phoneDAO.getPhoneById(id);
}
@Override
@Transactional
public void removePhone(int id) {
this.phoneDAO.removePhone(id);
}
24
Presentation Layer
Presentation Layer
Now we create a controller that handles the web requests dispatched via.
DispatcherServlet. Let the name of the controller be PhoneController and put it
under the package com.spring.demo.
@Controller:
@Autowired:
@RequestMapping
25
Presentation Layer
@Qualifier:
Used along with @Autowired to remove the conflict by specifying which exact
bean will be wired.
Created the following HomeController that will be used to return the default view
for our application.
HomeController.java
package com.spring.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class HomeController {
@RequestMapping(value="/")
public ModelAndView mainPage() {
return new ModelAndView("home");
}
@RequestMapping(value="/index")
public ModelAndView indexPage() {
return new ModelAndView("home");
}
}
26
PhoneContoller
PhoneContoller
PhoneController.java
package com.spring.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.spring.demo.model.Phone;
import com.spring.demo.service.PhoneService;
@Controller
public class PhoneController {
@Autowired(required = true)
@Qualifier(value = "phoneService")
public void setPhoneService(PhoneService ps) {
this.phoneService = ps;
}
27
PhoneContoller
if (p.getId() == 0) {
// new phone, add it
this.phoneService.addPhone(p);
} else {
// existing phone, call update
this.phoneService.updatePhone(p);
}
return "redirect:/phones";
@RequestMapping("/remove/{id}")
public String removePhone(@PathVariable("id") int id) {
this.phoneService.removePhone(id);
return "redirect:/phones";
}
@RequestMapping("/edit/{id}")
public String editPhone(@PathVariable("id") int id, Model mo
del) {
model.addAttribute("phone", this.phoneService.getPhoneBy
Id(id));
model.addAttribute("listPhones", this.phoneService.listP
hones());
return "phone";
}
}
`
@ModelAttribute:
This annotation is used for preparing the model data and also to define the
28
PhoneContoller
command object that would be bound with the HTTP request data.
This annotation can be applied on the methods as well as on the method
arguments.
In the above controller example, we used it on the argument of the
addPhone() method.
@PathVariable:
29
JSP
JSP
Even thought we can create multiple pages but here, we going to create one
single page which call add, edit, remove and list the data.
30
JSP
src/webapp/WEB-INF/views/phone.jsp
31
JSP
="form" %>
<%@ page session="false" %>
<html>
<head>
<title>Phone Page</title>
<style type="text/css">
.tg {border-collapse:collapse;border-spacing:0;border-c
olor:#ccc; cellpadding:10;
cellspacing:10;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padd
ing:10px 5px;border-style:solid;border-width:1px;overflow:hidden
;word-break:normal;border-color:#ccc;color:#333; cellpadding:10;
cellspacing:10;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font
-weight:normal;padding:10px 5px;border-style:solid;border-width:
1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#3
33;background-color:#f0f0f0; cellpadding:10;
cellspacing:10;}
.tg .tg-4eph{background-color:#f9f9f9}
a.button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 10px 15px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 15px;
margin: 10px 15px 10px 8px;
}
a.btn{
background-color: #f44336;
border: none;
color: white;
padding: 10px 15px;
text-align: center;
text-decoration: none;
display: inline-block;
32
JSP
font-size: 15px;
margin: 10px 15px 10px 8px;
}
.table {
border: 1px;
}
.th{ width:10%;
}
.value{
margin: 10px 15px 10px 8px;
}
</style>
</head>
<body>
<h1>
Add a Phone
</h1>
33
JSP
<form:label path="name">
<spring:message text="Name"/>
</form:label>
</td>
<td>
<form:input path="name" />
</td>
</tr>
<tr>
<td>
<form:label path="review">
<spring:message text="Review"/>
</form:label>
</td>
<td>
<form:input path="review" />
</td>
</tr>
<tr>
<td colspan="2">
<c:if test="${!empty phone.name}">
<input type="submit"
value="<spring:message text="Edit Phone"/>"
/>
</c:if>
<c:if test="${empty phone.name}">
<input type="submit"
value="<spring:message text="Add Phone"/>" /
>
</c:if>
</td>
</tr>
</table>
</form:form>
<br>
<h3>Phones List</h3>
<c:if test="${!empty listPhones}">
<table class="tg">
<tr>
<th width="80">ID</th>
34
JSP
</tr>
<c:forEach items="${listPhones}" var="phone">
<tr>
<td>${phone.id}</td>
<td>${phone.name}</td>
<td>${phone.review}</td>
<td><a href="<c:url value='/edit/${phone.id}' />" c
lass="button">Edit</a>
<a href="<c:url value='/remove/${phone.id}' />" cla
ss="btn">Delete</a></td>
</tr>
</c:forEach>
</table>
</c:if>
</body>
</html>
35
Web Configuration
Web Configuration
Now going to web configuration we can see the two configuration xmls. This will
be needed if you have multiple servlets and filters that shares common
parameters. You can define only one servlet config xml and put all of contents
from both xmls into the one. The tag <context-param> defines parameters that
are shared by all servlets and filters whereas <init-param> defines parameters
that are accessible by only that <servlet> inside which it is placed. We also
defined the DispatcherServlet which is the default request handler for all the
requests as defined by the pattern "/" in <url-pattern> .
<web-app>:
<context-param>:
<init-param>:
<listener>:
Defines a listener class to start up and shut down Spring's root application
36
Web Configuration
context.
We might not use this because we don't define the element <context-
param>
<servlet>:
<servlet-mapping>:
web.xml: /webapp/WEB-INF/web.xml
37
Web Configuration
38
servlet-context.xml
servlet-context.xml
The various components from the above xmls are described as follows:
<annotation-driven />:
This element should be placed in your DispatcherServlet context (or in your root
context if you have no DispatcherServlet context defined)
<context:component-scan>:
<resources>:
This tag allows static resource requests following a particular URL pattern to
be served by a ResourceHttpRequestHandler from any of a list of Resource
location.
39
servlet-context.xml
This provides a convenient way to serve static resources from location other
than the web application root, including locations on the classpath e.g.
<mvc:resources mapping="/resources/**" location="/,
classpath:/web-resources/"/>
InternalResourceViewResolver:
src/main/webapp/WEB-INF/sping/servlet-context.xml
40
servlet-context.xml
tory -->
<resources mapping="/resources/**" location="/resources/" />
41
servlet-context.xml
<beans:prop key="hibernate.show_sql">true</beans
:prop>
</beans:props>
</beans:property>
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManage
r"/>
</beans:beans>
42
Results
Results
Running the Application
Home Page
43
Results
Edit/Delete
44
Results
45