Over a million developers have joined DZone.
Gold Partner

Adding CRUD Capability to Spring MVC

· Java Zone

This article is intended for people who are interested in Spring and Hibernate, especially those who are new to the technology. Create, Read, Update and Delete capabilities are essential to a web based application. In this article, I'll be sharing how to add these capabilities to your Spring MVC application. I will be adding the CRUD (Create, Read/Retrieve, Update, Delete) capbility, which will be the operations performed on the database records prior to a certain domain object. We will be using Hibernate as our ORM and our database will be MySQL.

Advanced programmers are also welcome to comment and post suggestions in this article. I accept anything, whether it's positive or negative. :-)

Let us begin!

First, let us create a a Spring configuration resource named “SampleSpringMVC-dao.xml”

<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright : adobocode.com , 2010 -->
<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:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="paul.sydney.dataaccess" />
<tx:annotation-driven />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<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/my_dummy_db" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sessionFactoryGrabber" factory-bean="entityManagerFactory"
factory-method="getSessionFactory" />
<bean id="personDao" class="paul.sydney.dataaccess.PersonDaoImpl">
<property name="sessionFactory" ref="sessionFactoryGrabber" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactoryGrabber" />
</bean>
</beans>

 Let us then create a “personForm.jsp”  (note that the Save and Delete button has the same name and they only differ in value):

<!-- Copyright : adobocode.com , 2010 -->
<%@ page language="java" session="false"
contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>Adobocode : Sample Spring MVC using Forms</title>
</head>
<body>
<h2>Adobocode : Person Form</h2>
<form:form modelAttribute="person">
<form:hidden path="id" />
<fieldset>
<table>
<tr>
<td>Name</td>
<td><form:input path="name" /><form:errors path="name" /></td>
</tr>
<tr>
<td>Age</td>
<td><form:input path="age" /><form:errors path="age" /></td>
</tr>
<tr>
<td>Address</td>
<td><form:input path="address" /><form:errors path="address" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" id="save" name="action" value="Save" />
<input type="submit" id="delete" name="action" value="Delete" /> <input
type="submit" name="_eventId_cancel" value="Cancel" /></td>
</tr>
</table>
</fieldset>
</form:form>
</body>
</html>

 Now, let us create and annotate our model class Person with JPA:

package paul.sydney.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Copyright : adobocode.com , 2010
*
* @author Paul Sydney Orozco | xtrycatchx@gmail.com
*/
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue
@Column(name = "person_id")
private int id;
@Column(name = "person_name")
private String name;
@Column(name = "person_age")
private int age;
@Column(name = "person_address")
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

 Now let us create our DAO layer. First, let us create an interface “PersonDao”

package paul.sydney.dao;
import java.util.List;
import paul.sydney.model.Person;
/**
* Copyright : adobocode.com , 2010
*
* @author Paul Sydney Orozco | xtrycatchx@gmail.com
*/
public interface PersonDao {
public void savePerson(Person person);
public void deletePerson(Person person);
public List retrieveAll();
public Person retrievePerson(int id);
}

 and it's implementing class:

package paul.sydney.dataaccess;
import java.util.List;
import org.hibernate.LockMode;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import paul.sydney.dao.PersonDao;
import paul.sydney.model.Person;
/**
* Copyright : adobocode.com , 2010
*
* @author Paul Sydney Orozco | xtrycatchx@gmail.com
*/
@Repository("personDao")
public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao {
public PersonDaoImpl() {
super();
}
@Override
public void deletePerson(Person person) {
getHibernateTemplate().delete(person, LockMode.NONE);
}
@Override
public List retrieveAll() {
List personList = getHibernateTemplate().loadAll(Person.class);
return personList;
}
@Override
public Person retrievePerson(int id) {
return (Person) getHibernateTemplate().get(Person.class, id);
}
@Override
public void savePerson(Person person) {
getHibernateTemplate().saveOrUpdate(person);
}
}

 and the business modules that relies on those DAO layer:

package paul.sydney.service;
import java.util.List;
import paul.sydney.model.Person;
/**
* Copyright : adobocode.com , 2010
* @author Paul Sydney Orozco | xtrycatchx@gmail.com
*/
public interface IDummyService {
public List getDummyList();
public Person retrievePerson(int id);
public void savePerson(Person person);
public void deletePerson(Person person);
}

 and it's implementing class:

package paul.sydney.service;
import paul.sydney.dao.PersonDao;
import paul.sydney.model.Person;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;
/**
* Copyright : adobocode.com , 2010
*
* @author Paul Sydney Orozco | xtrycatchx@gmail.com
*/

@Service("dummyService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = false)
public class DummyService implements IDummyService {
@Autowired
private PersonDao personDao;
public List getDummyList() {
return this.personDao.retrieveAll();
}
public Person retrievePerson(int id) {
return this.personDao.retrievePerson(id);
}
public void savePerson(Person person) {
this.personDao.savePerson(person);
}
@Override
public void deletePerson(Person person) {
this.personDao.deletePerson(person);
}
}

and finally the Controller which will consume the service/business layer:

package paul.sydney.controller;
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.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import paul.sydney.controller.validation.PersonValidator;
import paul.sydney.model.Person;
import paul.sydney.service.IDummyService;
/**
* PersonForm class, form controller for the 'personForm.jsp'
* Copyright : www.adobocode.com , 2010
*
* @author Paul Sydney Orozco | xtrycatchx@gmail.com
*
*/
@Controller
@RequestMapping("/personForm.htm")
@SessionAttributes("person")
public class PersonForm {
@Autowired
private IDummyService dummyService;
private final String SAVE_ACTION = "Save";
private final String PARAM_ACTION = "action";
private final String PERSON_ATTRIBUTE = "person";
private final String PERSON_ID = "personId";
private final String PERSON_FORM = "personForm";
private final String PERSON_DISPLAY = "redirect:personDisplay.htm";
@RequestMapping(method = RequestMethod.GET)
public Person setupForm(
@RequestParam(value = PERSON_ID, required = false) Integer id) {
if (id == null) {
return new Person();
} else {
return this.dummyService.retrievePerson(id);
}
}
@RequestMapping(method = RequestMethod.POST)
public String save(@ModelAttribute(PERSON_ATTRIBUTE) Person person,
BindingResult result, SessionStatus status,
@RequestParam(PARAM_ACTION) String request) {
if (SAVE_ACTION.equals(request)) {
new PersonValidator().validate(person, result);
if (result.hasErrors()) {
return PERSON_FORM;
} else {
this.dummyService.savePerson(person);
status.setComplete();
return PERSON_DISPLAY;
}
} else {
this.dummyService.deletePerson(person);
status.setComplete();
return PERSON_DISPLAY;
}
}
}

These are the things needed  in your existing Spring MVC application in order to cater for CRUD capability. Hope you guys learn something.

For the basic Spring MVC Tutorial : Basic Spring Tutorial

For adding validations for Spring Forms : Adding Validations to Spring MVC forms

More stuff can be found at : www.adobocode.com

 

Topics:

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}