Saturday, January 8, 2011

Spring MVC 3, Hibernate Annotations, MySQL Integration Tutorial

In this tutorial we will build a simple Spring MVC 3 application for managing a list of persons. We will provide a simple CRUD system for viewing, adding, editing, and deleting of persons. For the persistence layer, we will use Hibernate 3 annotations and use MySQL as our database, though the application is flexible enough to utilize different databases. A prior knowledge of MVC, ORM, and SQL is assumed in this tutorial. This tutorial is similar with Spring 3 MVC - Hibernate 3: Using Annotations Integration Tutorial

Spring MVC 3 and Hibernate Tutorials Series
Spring - Hibernate: Many-To-One Association - Explicitly Specify Join Table, Cascade, and Fetch
Spring - Hibernate: One-To-Many Association - Explicitly Specify Join Table, Cascade, and Fetch
Spring - Hibernate: Many-To-One Association
Spring - Hibernate: One-To-Many Association
Spring MVC 3, Hibernate Annotations, MySQL Integration Tutorial
Spring MVC 3, Hibernate Annotations, HSQLDB Integration Tutorial

What is Hibernate?
Hibernate is an object-relational mapping (ORM) library for the Java language, providing a framework for mapping an object-oriented domain model to a traditional relational database. Hibernate solves object-relational impedance mismatch problems by replacing direct persistence-related database accesses with high-level object handling functions

Source: http://en.wikipedia.org/wiki/Hibernate_(Java)

What is MySQL?
The MySQL Database powers the most demanding Web, E-commerce and Online Transaction Processing (OLTP) applications. It is a fully integrated transaction-safe, ACID compliant database with full commit, rollback, crash recovery and row level locking capabilities. MySQL delivers the ease of use, scalability, and performance that has made MySQL the world's most popular open source database. Some of the world's most trafficked websites like Facebook, Google, ticketmaster, and eBay rely on MySQL for their business critical applications.

Source: http://www.mysql.com/products/enterprise/database/
Let's preview first the final structure of our project.

And here's how our application would look like:
It's a simple, crude CRUD system (pun intended).

We start by defining our domain object Person

Person

package org.krams.tutorial.domain;

import java.io.Serializable;

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

/**
 * For a complete reference see 
 * 
 * Hibernate Annotations Communit Documentations
 */
@Entity
@Table(name = "PERSON")
public class Person implements Serializable {

 private static final long serialVersionUID = -5527566248002296042L;
 
 @Id
 @Column(name = "ID")
 @GeneratedValue
 private Integer id;
 
 @Column(name = "FIRST_NAME")
 private String firstName;
 
 @Column(name = "LAST_NAME")
 private String lastName;
 
 @Column(name = "MONEY")
 private Double money;

 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;
 }

 public Double getMoney() {
  return money;
 }

 public void setMoney(Double money) {
  this.money = money;
 }
}
Person is a simple POJO containing four private fields:
id
firstName
lastName
money
Each of these fields have been annotated with @Column and assigned with corresponding names.
ID
FIRST_NAME
LAST_NAME
MONEY
These column names are database column names. You don't deal with them. Instead, Hibernate is the one responsible for managing your database. However, you are responsible for declaring the column names in the POJO. You don't declare them in your database. Remember your database doesn't exist yet.

The POJO has been annotated to map to a database table. If you look at the declaration of the Person class we see the annotation @Table and the name of the actual table:

@Entity
@Table(name = "PERSON")
public class Person implements Serializable
Notice the annotation @Entity before the @Table. This tells Hibernate that this POJO should be mapped to a database table.

Since we will manipulate a list of persons, let's declare a service that manipulates a list of Persons.

PersonService
package org.krams.tutorial.service;

import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.krams.tutorial.domain.Person;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Service for processing Persons
 * 
 */
@Service("personService")
@Transactional
public class PersonService {

 protected static Logger logger = Logger.getLogger("service");
 
 @Resource(name="sessionFactory")
 private SessionFactory sessionFactory;
 
 /**
  * Retrieves all persons
  * 
  * @return a list of persons
  */
 public List getAll() {
  logger.debug("Retrieving all persons");
  
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
  
  // Create a Hibernate query (HQL)
  Query query = session.createQuery("FROM  Person");
  
  // Retrieve all
  return  query.list();
 }
 
 /**
  * Retrieves a single person
  */
 public Person get( Integer id ) {
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
  
  // Retrieve existing person first
  Person person = (Person) session.get(Person.class, id);
  
  return person;
 }
 /**
  * Adds a new person
  */
 public void add(Person person) {
  logger.debug("Adding new person");
  
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
  
  // Save
  session.save(person);
 }
 
 /**
  * Deletes an existing person
  * @param id the id of the existing person
  */
 public void delete(Integer id) {
  logger.debug("Deleting existing person");
  
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
  
  // Retrieve existing person first
  Person person = (Person) session.get(Person.class, id);
  
  // Delete 
  session.delete(person);
 }
 
 /**
  * Edits an existing person
  */
 public void edit(Person person) {
  logger.debug("Editing existing person");
  
  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();
  
  // Retrieve existing person via id
  Person existingPerson = (Person) session.get(Person.class, person.getId());
  
  // Assign updated values to this person
  existingPerson.setFirstName(person.getFirstName());
  existingPerson.setLastName(existingPerson.getLastName());
  existingPerson.setMoney(existingPerson.getMoney());

  // Save updates
  session.save(existingPerson);
 }
}
We've declared a simple CRUD system with the following methods:
getAll()
add()
delete()
edit()
In each method we retrieve the session:
Session session = sessionFactory.getCurrentSession();
This is similar to retrieving a connection from the database so that we can do our work. The Session object provides numerous methods for persisting objects. For this tutorial, we use the following Session methods:
session.createQuery()
session.save()
session.delete()
We're done with the domain and the service layer. Let's move to the Spring controller.

MainController
package org.krams.tutorial.controller;

import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.krams.tutorial.domain.Person;
import org.krams.tutorial.service.PersonService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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;


/**
 * Handles and retrieves person request
 */
@Controller
@RequestMapping("/main")
public class MainController {

 protected static Logger logger = Logger.getLogger("controller");
 
 @Resource(name="personService")
 private PersonService personService;
 
 /**
  * Handles and retrieves all persons and show it in a JSP page
  * 
  * @return the name of the JSP page
  */
    @RequestMapping(value = "/persons", method = RequestMethod.GET)
    public String getPersons(Model model) {
     
     logger.debug("Received request to show all persons");
     
     // Retrieve all persons by delegating the call to PersonService
     List persons = personService.getAll();
     
     // Attach persons to the Model
     model.addAttribute("persons", persons);
     
     // This will resolve to /WEB-INF/jsp/personspage.jsp
     return "personspage";
 }
    
    /**
     * Retrieves the add page
     * 
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/persons/add", method = RequestMethod.GET)
    public String getAdd(Model model) {
     logger.debug("Received request to show add page");
    
     // Create new Person and add to model
     // This is the formBackingOBject
     model.addAttribute("personAttribute", new Person());

     // This will resolve to /WEB-INF/jsp/addpage.jsp
     return "addpage";
 }
 
    /**
     * Adds a new person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/add", method = RequestMethod.POST)
    public String add(@ModelAttribute("personAttribute") Person person) {
  logger.debug("Received request to add new person");
  
     // The "personAttribute" model has been passed to the controller from the JSP
     // We use the name "personAttribute" because the JSP uses that name
  
  // Call PersonService to do the actual adding
  personService.add(person);

     // This will resolve to /WEB-INF/jsp/addedpage.jsp
  return "addedpage";
 }
    
    /**
     * Deletes an existing person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/delete", method = RequestMethod.GET)
    public String delete(@RequestParam(value="id", required=true) Integer id, 
              Model model) {
   
  logger.debug("Received request to delete existing person");
  
  // Call PersonService to do the actual deleting
  personService.delete(id);
  
  // Add id reference to Model
  model.addAttribute("id", id);
     
     // This will resolve to /WEB-INF/jsp/deletedpage.jsp
  return "deletedpage";
 }
    
    /**
     * Retrieves the edit page
     * 
     * @return the name of the JSP page
     */
    @RequestMapping(value = "/persons/edit", method = RequestMethod.GET)
    public String getEdit(@RequestParam(value="id", required=true) Integer id,  
              Model model) {
     logger.debug("Received request to show edit page");
    
     // Retrieve existing Person and add to model
     // This is the formBackingOBject
     model.addAttribute("personAttribute", personService.get(id));
     
     // This will resolve to /WEB-INF/jsp/editpage.jsp
     return "editpage";
 }
    
    /**
     * Edits an existing person by delegating the processing to PersonService.
     * Displays a confirmation JSP page
     * 
     * @return  the name of the JSP page
     */
    @RequestMapping(value = "/persons/edit", method = RequestMethod.POST)
    public String saveEdit(@ModelAttribute("personAttribute") Person person, 
                 @RequestParam(value="id", required=true) Integer id, 
                Model model) {
     logger.debug("Received request to update person");
    
     // The "personAttribute" model has been passed to the controller from the JSP
     // We use the name "personAttribute" because the JSP uses that name
     
     // We manually assign the id because we disabled it in the JSP page
     // When a field is disabled it will not be included in the ModelAttribute
     person.setId(id);
     
     // Delegate to PersonService for editing
     personService.edit(person);
     
     // Add id reference to Model
  model.addAttribute("id", id);
  
     // This will resolve to /WEB-INF/jsp/editedpage.jsp
  return "editedpage";
 }
    
}
This controller declares the following mappings:
/persons - for retrieving all persons
/persons/add (GET) - displays the Add New form
/persons/add (POST) - saves the new person
/persons/delete - deletes an existing person
/persons/edit (GET) - displays the Edit form
/persons/edit (POST) - saves the edited person

Each mapping delegates the call to the PersonService. When the PersonService is done processing, the controller then forwards the request to a JSP page that displays a confirmation message. Here are the JSP pages.

personspage.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Persons</h1>

<c:url var="addUrl" value="/krams/main/persons/add" />
<table style="border: 1px solid; width: 500px; text-align:center">
 <thead style="background:#fcf">
  <tr>
   <th>First Name</th>
   <th>Last Name</th>
   <th>Money</th>
   <th colspan="3"></th>
  </tr>
 </thead>
 <tbody>
 <c:forEach items="${persons}" var="person">
   <c:url var="editUrl" value="/krams/main/persons/edit?id=${person.id}" />
   <c:url var="deleteUrl" value="/krams/main/persons/delete?id=${person.id}" />
  <tr>
   <td><c:out value="${person.firstName}" /></td>
   <td><c:out value="${person.lastName}" /></td>
   <td><c:out value="${person.money}" /></td>
   <td><a href="${editUrl}">Edit</a></td>
   <td><a href="${deleteUrl}">Delete</a></td>
   <td><a href="${addUrl}">Add</a></td>
  </tr>
 </c:forEach>
 </tbody>
</table>

<c:if test="${empty persons}">
 There are currently no persons in the list. <a href="${addUrl}">Add</a> a person.
</c:if>

</body>
</html>
editpage.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h1>Edit Person</h1>

<c:url var="saveUrl" value="/krams/main/persons/edit?id=${personAttribute.id}" />
<form:form modelAttribute="personAttribute" method="POST" action="${saveUrl}">
 <table>
  <tr>
   <td><form:label path="id">Id:</form:label></td>
   <td><form:input path="id" disabled="true"/></td>
  </tr>
 
  <tr>
   <td><form:label path="firstName">First Name:</form:label></td>
   <td><form:input path="firstName"/></td>
  </tr>

  <tr>
   <td><form:label path="lastName">Last Name</form:label></td>
   <td><form:input path="lastName"/></td>
  </tr>
  
  <tr>
   <td><form:label path="money">Money</form:label></td>
   <td><form:input path="money"/></td>
  </tr>
 </table>
 
 <input type="submit" value="Save" />
</form:form>

</body>
</html>
addpage.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h1>Create New Person</h1>

<c:url var="saveUrl" value="/krams/main/persons/add" />
<form:form modelAttribute="personAttribute" method="POST" action="${saveUrl}">
 <table>
  <tr>
   <td><form:label path="firstName">First Name:</form:label></td>
   <td><form:input path="firstName"/></td>
  </tr>

  <tr>
   <td><form:label path="lastName">Last Name</form:label></td>
   <td><form:input path="lastName"/></td>
  </tr>
  
  <tr>
   <td><form:label path="money">Money</form:label></td>
   <td><form:input path="money"/></td>
  </tr>
 </table>
 
 <input type="submit" value="Save" />
</form:form>

</body>
</html>
editedpage.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="java.util.Date" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h1>Persons</h1>

<p>You have edited a person with id ${id} at <%= new java.util.Date() %></p>

<c:url var="mainUrl" value="/krams/main/persons" />
<p>Return to <a href="${mainUrl}">Main List</a></p>

</body>
</html>
addedpage.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="java.util.Date" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h1>Persons</h1>

<p>You have added a new person at <%= new java.util.Date() %></p>

<c:url var="mainUrl" value="/krams/main/persons" />
<p>Return to <a href="${mainUrl}">Main List</a></p>

</body>
</html>
deletedpage.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="java.util.Date" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h1>Persons</h1>

<p>You have deleted a person with id ${id} at <%= new java.util.Date() %></p>

<c:url var="mainUrl" value="/krams/main/persons" />
<p>Return to <a href="${mainUrl}">Main List</a></p>

</body>
</html>

Let's complete our Spring MVC application by declaring the required configurations.

To enable Spring MVC we need to add in the web.xml

web.xml
<servlet>
  <servlet-name>spring</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>spring</servlet-name>
  <url-pattern>/krams/*</url-pattern>
 </servlet-mapping>

 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
Take note of the URL pattern. When accessing any pages in our MVC application, the host name must be appended with
/krams
In the web.xml we declared a servlet-name spring. By convention, we must declare a spring-servlet.xml as well.

spring-servlet.xml
<!-- Declare a view resolver -->
 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
      p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
By convention, we must declare an applicationContext.xml as well.

applicationContext.xml
<!-- Activates various annotations to be detected in bean classes -->
 <context:annotation-config />
 
 <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
  For example @Controller and @Service. Make sure to set the correct base-package-->
 <context:component-scan base-package="org.krams.tutorial" />
 
 <!-- Configures the annotation-driven Spring MVC Controller programming model.
 Note that, with Spring 3.0, this tag works in Servlet MVC only!  -->
 <mvc:annotation-driven /> 
 
 <!-- Load Hibernate related configuration -->
 <import resource="hibernate-context.xml" />
Notice in the applicationContext.xml, we declared the following import:
<import resource="hibernate-context.xml" />
This contains the Hibernate configuration files

<?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:p="http://www.springframework.org/schema/p" 
        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/tx 
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
      ">

 <context:property-placeholder location="/WEB-INF/spring.properties" />
    
    <!-- Enable annotation style of managing transactions -->
 <tx:annotation-driven transaction-manager="transactionManager" /> 
   
    <!-- Declare the Hibernate SessionFactory for retrieving Hibernate sessions -->
    <!-- See http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.html -->        
 <!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/SessionFactory.html -->
 <!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/Session.html -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
     p:dataSource-ref="dataSource"
     p:configLocation="${hibernate.config}"
     p:packagesToScan="org.krams.tutorial"/>
 
 <!-- Declare a datasource that has pooling capabilities-->  
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close"
    p:driverClass="${app.jdbc.driverClassName}"
    p:jdbcUrl="${app.jdbc.url}"
    p:user="${app.jdbc.username}"
    p:password="${app.jdbc.password}"
    p:acquireIncrement="5"
    p:idleConnectionTestPeriod="60"
    p:maxPoolSize="100"
    p:maxStatements="50"
    p:minPoolSize="10" />

 <!-- Declare a transaction manager-->
 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
          p:sessionFactory-ref="sessionFactory" />
  
</beans>
We basically encapsulated all Hibernate and Spring related configurations in this one XML file. Here's what happening within the config:

1. Enable transaction support through Spring annotations:
<tx:annotation-driven transaction-manager="transactionManager" />
2. Declare the Hibernate SessionFactory:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
     p:dataSource-ref="dataSource"
     p:configLocation="${hibernate.config}"
     p:packagesToScan="org.krams.tutorial"/>
A SessionFactory is a factory that produces Session objects. It's analogous to a real Car Factory or Car Assemblies where its job is to make cars for humans.

What is a Session?
The main function of the Session is to offer create, read and delete operations for instances of mapped entity classes.

Source: http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/Session.html

A SessionFactory requires a datasource. The datasource in this tutorial is the database.

A SessionFactory requires a configLocation. The configLocation contains Hibernate-specific configurations. Here's our Hibernate-specific config file:

hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  
<hibernate-configuration>
  <session-factory>
   <!-- We're using MySQL database so the dialect needs to MySQL as well-->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
    <!-- Enable this to see the SQL statements in the logs-->
    <property name="show_sql">false</property>
    <!-- This will drop our existing database and re-create a new one.
      Existing data will be deleted! -->
    <property name="hbm2ddl.auto">create</property>
  </session-factory>
</hibernate-configuration>
Here we declared the type of database to be used. We are using MySQL so we use a MySQL dialect. We're using a specialized MySQL5InnoDBDialect because we decided to use the InnoDB storage engine for MySQL.

What's MySQL InnoDB?
InnoDB is a transaction-safe (ACID compliant) storage engine for MySQL that has commit, rollback, and crash-recovery capabilities to protect user data.

Source: http://dev.mysql.com/doc/refman/5.0/en/innodb-storage-engine.html
Returning back to the SessionFactory bean declaration, it also requires the property packagesToScan. This is to indicate where our annotated entities are located. In this tutorial, it's under the org.krams.tutorial

3. Declare a datasource:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
 destroy-method="close"
 p:driverClass="${app.jdbc.driverClassName}"
 p:jdbcUrl="${app.jdbc.url}"
 p:user="${app.jdbc.username}"
 p:password="${app.jdbc.password}"
 p:acquireIncrement="5"
 p:idleConnectionTestPeriod="60"
 p:maxPoolSize="100"
 p:maxStatements="50"
 p:minPoolSize="10" />
Our datasource uses C3P0 for pooling to allow efficient access to our database. Why do we need to wrap our datasource with a connection pool?
JDBC connections are often managed via a connection pool rather than obtained directly from the driver. Examples of connection pools include BoneCP, C3P0 and DBCP.

Source: http://en.wikipedia.org/wiki/Java_Database_Connectivity

What is Pooling?
In software engineering, a connection pool is a cache of database connections maintained so that the connections can be reused when future requests to the database are required. Connection pools are used to enhance the performance of executing commands on a database. Opening and maintaining a database connection for each user, especially requests made to a dynamic database-driven website application, is costly and wastes resources. In connection pooling, after a connection is created, it is placed in the pool and it is used over again so that a new connection does not have to be established.

Source: http://en.wikipedia.org/wiki/Connection_pool

For more info on configuring C3P0, you can check this reference from JBoss: HowTo configure the C3P0 connection pool. For a list of other pooling providers, see Open Source Database Connection Pools

The database-specific configuration are contained within a properties file.

spring.properties

mydatabase is the name of our MySQL dabatase.

As an alternative, we can enter these properties directly within the hibernate-context.xml

This is exactly similar to the following:


The benefit of using a separate properties file is we encapsulate all database-specific configs within a separate file. The hibernate-context.xml purpose is to encapsulate Hibernate-related config not database properties.

That's it. We've completed our application. We've managed to setup a simple Spring MVC 3 application that uses Hibernate Annotations to encapsulate persistence access to a MySQL database. We've also leveraged Spring's simple MVC programming model.

To access the main page, enter the following URL:
http://localhost:8080/spring-hibernate-mysql/krams/main/persons
The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-hibernate-annotations-integration-tutorial/

You can download the project as a Maven build. Look for the spring-hibernate-mysql.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

If you want to learn more about Spring MVC and integration with other technologies, feel free to read my other tutorials in the Tutorials section.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3, Hibernate Annotations, MySQL Integration Tutorial ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

138 comments:

  1. Thank you for posting this... I have been looking at example Spring - Hibernate Apps for a few days and all seemed to have a major flaw (too outdated, didn't use Spring MVC, etc) and this is a great, modern example for someone new to the framework

    ReplyDelete
  2. I receive an error: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.hql.ast.QuerySyntaxException: person is not mapped [FROM person]

    Seems you foget about mapping XML

    ReplyDelete
  3. Sorry, my mistake. I am wrote:
    Query query = session.createQuery("FROM person");
    Instead of:
    Query query = session.createQuery("FROM Person");

    ReplyDelete
  4. @Skif, I'm glad you sorted it out. Regarding the mapping XML, this tutorial doesn't need one since it uses annotations. The mapping is within the POJO itself.

    ReplyDelete
  5. @krams, thank you very much for your tutorials. It's very usefull. Just few mistakes, in this one, what I found.

    You wrote in PersonService, edit method:
    existingPerson.setFirstName(person.getFirstName());
    existingPerson.setLastName(existingPerson.getLastName());
    existingPerson.setMoney(existingPerson.getMoney());
    Instead of:
    existingPerson.setFirstName(person.getFirstName());
    existingPerson.setLastName(person.getLastName());
    existingPerson.setMoney(person.getMoney());

    And in case of direct properties within the hibernate-context.xml:
    Line must be deleted.
    Attribute of sessionFactory p:configLocation="${hibernate.config}" must be changed to p:configLocation="/WEB-INF/hibernate.cfg.xml"

    Thank you for your work!

    ReplyDelete
  6. Opps, Google eating tags:
    Tag context:property-placeholder location="/WEB-INF/spring.properties" must be deleted.

    ReplyDelete
  7. Hi Krams,
    Thanks a lot for your initiative. I really learned a lot from your tutorials. I need some technical guidance from you.
    I am developing REST based web services using Spring MVC REST & JPA 2.0 & HIBERNATE 3.6.0
    My Service consumer is PHP application. Depending on the Accept header, my service sends output in XML or JSON.
    My Question is how to support images and videos?
    And also I am writing JAXB and JPA annotations on domain classes. I am not writing XSD first and generated classes using XJC. It is working fine for simple XML. But if I want to generate customized XML with JPA relation ships such as one to many, I am not able to achieve what I want. I am planning to use MOXy JAXB annotations. Can I use MOXy JAXB with JPA & Hibernate?
    Also how to handle exceptions?
    Finally, I have one more question. I need to put validation on image. User cannot upload image more than 3mb. How best can I put this validation in Spring MVC? Please suggest.

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. @Srinivas, there are some available tutorials that show how to support images via Spring Rest in the web. Unfortunately you will have to pieced them up most of them just shows you a part of the puzzle. You will have to use @ResponseBody and output the result as a byte[]. You will have to use Spring's ByteArrayConverter (if I remember correctly, maybe the name is wrong). If I have the time, I will try to make a tutorial for that.

    ReplyDelete
  10. @Skif, thanks for the info. I updated the Maven project that uses the correct code. I'll update the PersonService in this blog later.

    ReplyDelete
  11. Nice Tutorial. Thanks for sharing this.

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. There is a problem when y run the application the base mysql become empty so what do you do? , please i need a solution

    ReplyDelete
  14. @Anonymous, in the hibernate-cfg.xml file, there's a property "hbm2ddl.auto" set to "create". Everytime you run the application, it will drop the whole database and create a new from scratch. If you want to disable that feature, set the value to update or remove the whole property.

    ReplyDelete
  15. Big thank you krams for this tutorial it's very helpful

    ReplyDelete
  16. Thanks for this! Makes getting started a whole lot easier.

    ReplyDelete
  17. Thanks for this tutorial.

    I am new to Spring framework, this tutorial looks very easy and helpfull.

    My question please :

    I downloaded :
    spring-hibernate-mysql.zip

    how to open it in Eclipse or Netbeans ?

    Thanks, your help is appreciated.

    ReplyDelete
  18. @Anonymous, you have to have Maven installed. Then open a command line. Go to where you saved the project. And run on the commandline "mvn:eclipse". This should import the project for Eclipse. If you don't want Maven, just copy the files to your Eclipse and download manually the jars

    ReplyDelete
  19. Though project built successfully and deployed too on the url 'http://localhost:8080/spring-hibernate-mysql/krams/main/persons' error 404 comes. Could you please help?

    ReplyDelete
  20. Excellent post. You did something which Hibernate guys havent bothered for years i.e adding meaning examples in sample/ hibernate download. Nor have the authors of so many Spring/Hibernate books by just limiting examples to running from main method.Shame on them. Thanks from bottom of heart and keep the good work going.

    ReplyDelete
  21. just two minor corrections I required. change in jdbc url jdbc:mysql://localhost:3306/mydatabase instead of jdbc:mysql://localhost/mydatabase and addition of
    org.mortbay.jetty
    maven-jetty-plugin

    ReplyDelete
  22. Excellent tutorial. Could you kindly try an integration of Spring, Hibernate and Oracle with stored procedures and functions. There are no good up to date tutorials to illustrate them. If you could take time off in developing a project to illustrate them, it would be a great eye opener for beginners. Thanks in advance. Great job. Cheers.

    ReplyDelete
  23. Exactly... Oracle Stored procedure/ Function implementation would be terrific. No good tutorial around except http://timezra.blogspot.com/2008/10/spring-hibernate-and-oracle-stored.html.

    ReplyDelete
  24. Very Nice...

    Thank you for sharing this....

    ReplyDelete
  25. Thanks for sharing this. I have referred this tutorial as well as spring MVC- jquery integration tutorial..and both have helped me immensely.

    -Rohit

    ReplyDelete
  26. Hi krams,

    Thank you for your example. Could you provide a location for the binary jar files you used in your lib directory or classpath?

    --thanks for your time.

    Bret Mullinix

    ReplyDelete
  27. I've downloaded binary files that are required to compile the project. However, the binary files might not be the correct version(s). I keep on getting an error trying to connect to mysql with the C3P0 driver. If you can't provide the dependent jar files, can you list the required jars and versions for this example.

    --thanks again

    Bret Mullinix

    ReplyDelete
  28. thnaks for this

    ReplyDelete
  29. Hi Krams,

    Nice tutorial.. Iam new to Spring..my requirements at a time data will be inserted multiple tables..plz help me..

    Thanks in advance

    kavitha

    ReplyDelete
  30. Hi Kram, My IDE point to error for List should it actually be List ?
    By the way a very good tutorial

    ReplyDelete
  31. thanx a lot...
    very nice tutorial for a beginner :)

    ReplyDelete
  32. Krams, you are the man. Ran right out-of-the box (only pointed it at the database). No other MVC/Spring/Hibernate/MySQL example even comes close. And believe me, I've looked. Thank you.

    ReplyDelete
  33. Thanks u r tutorial.

    ReplyDelete
  34. Again amazing tutorial ,
    you should make DAO classes ,
    and another thing , 1 con with p: way , you can't know the whole property list ,
    with the 'normal' way


    will give you a list of all property avaible

    ReplyDelete
  35. Your comments and explains are excellents , sometimes the comments were more needed that the code for my project :)

    ReplyDelete
  36. thank you very much for the tutorial.I have a single doubt i have seen in the other examples in the other websites where they have used a JPAtransactionmanager and persistenece.xml instead of hibernate.cfg.xml and hibernatetransaction manager.
    Previously i thought this is due to the fact that we are using JPA instead of xml configuration but here you have used JPA but still continue to use hibernate.cfg.xml and hibernatetransaction manager.I am total noob and have just started Hibernate so can you explain me.
    Thanks again.

    ReplyDelete
  37. @myths, thanks for the comments. It would be better if you can point to me those examples you've seen. I'm sure there's a logical reason why their examples are using a persistence.xml and etc. For this guide, we're using the a hibernate.cfg.xml and etc, it's because we're using Hibernate's SessionFactory. If you check my latest tutorial Spring MVC: Integrating MySQL, MongoDB, RabbitMQ, and AJAX, we're still using Hibernate as our ORM but we're using a persistence.xml. That's because we're using an EntityManagerFactory over there. I suggest you compare the configuration files for that one and this guide. In any case, JPA "itself is just a specification, not a product; it cannot perform persistence or anything else by itself. JPA is just a set of interfaces, and requires an implementation. - http://en.wikibooks.org/wiki/Java_Persistence/What_is_JPA%3F". In this guide we're using the JPA annotations and SessionFactory but we're not using the EntityManagerFactory, but if we do, then we need to have the persistence.xml and alike

    ReplyDelete
  38. @Krams
    Thanks a lot again.your quick replies and the amazing examples covering all the goodies available there makes your blog the best for these technologies.
    You are right they are using EntityManagerFactory and have thus used the persistence.xml.
    Sir if i may not troubling you i have another question.Can you explain me the conditions where EntityManagerFactory and persistence.xml are preferred over Hibernate's SessionFactory and cfg.xml.I have a requirement where we are using the ORM as hibernate and integrating it with Spring MVC3 now i have this fuzzy situation where i have to take an opinion.
    I am sorry if there is dumbness in my question as i have just started with hibernate stuff.
    Thanks for your replies.

    ReplyDelete
  39. @myths, your question is perfectly valid. It is better to use the EntityManagerFactory/JPA so that you're not locked-in to a particular ORM provider (i.e Hibernate). Take note though that Hibernate had a big influence on the JPA spec. "Gavin King founded[6] Hibernate. He represented JBoss on JSR220,[7] the JCP expert group charged with developing JPA. This led to ongoing controversy and speculation surrounding the relationship between JPA and Hibernate. Sun Microsystems has stated[8] that ideas came from several frameworks, including Hibernate and JDO." - Wikipedia. In other words, if you sticked with JPA, rest-assured Hibernate is always there. If in case, you want to replace Hibernate, then all you need to do is change configs. Your code stays the same.

    ReplyDelete
  40. @Krams

    Thanks a tonne.I owe you a lot for your support to the programming community.we are bunch of freelancers and have gained immensely from your blogspot.Keep guiding us in our future endeavors.
    thanking you again.

    ReplyDelete
  41. How would you validate the inputs from the person add form?
    Many thanks for an excellent tutorial.

    ReplyDelete
  42. @robertom, you can use the jquery-validate plugin. See http://bassistance.de/jquery-plugins/jquery-plugin-validation/

    ReplyDelete
  43. I am getting the following exception when I am deploying.
    [ERROR] [main 05:03:18] (ContextLoader.java:initWebApplicationContext:215) Context initialization failed
    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/mvc]
    Offending resource: ServletContext resource [/WEB-INF/applicationContext.xml]

    at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:80)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:281)

    Please help me

    ReplyDelete
  44. @Anonymous, are you using the latest Spring jars? It appears either you haven't declared the mvc tag in your config file or there's a missing bean. Based on the error it's under the applicationContext.xml. What's in there?

    ReplyDelete
  45. how to run the above application?

    i saw some examples,in that they are using ModelandView methods in the controller class
    is it neccessary that?

    ReplyDelete
  46. how to run the above application in eclipse indigo
    iam using tomcat6,jdk1.6

    and iam not using maven
    iam using ant

    ReplyDelete
  47. For the error reported on September 23, 2011 6:17 PM

    This is my applicationContext.xml


















    Can you please list the required jars for this application. I'm using spring web flow jars and mysql connector and servlet api. Please make me clear.

    ReplyDelete
  48. Seems like it doesn't allow to put xml content as it is. So this is the extra things i added more that your applicationContext.xml

    ReplyDelete
  49. Since I couldn't post my applicationContext.xml. I just replace it from your once. But still I'm getting errors.
    [ERROR] [main 12:11:26] (ContextLoader.java:initWebApplicationContext:215) Context initialization failed
    org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 2 in XML document from ServletContext resource [/WEB-INF/applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException: The prefix "context" for element "context:annotation-config" is not bound.
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:404)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)

    ReplyDelete
  50. Hi krams

    I have a problem when ever i used applicationContext.xml in my project and use ContextLoaderListener in my web.xml i found error HTTP Status 404

    If i remove this and used just dispatcher servlet my program work fine

    plz tell me what is this problem


    Thanks

    ReplyDelete
  51. Hi Krams,

    I'm experiencing an error,
    [ERROR] [main 06:20:37] (JDBCExceptionReporter.java:logExceptions:101) Connections could not be acquired from the underlying database!
    Already change the username and password from the spring.properties. And the mysql is already up. What would be the problem?

    ReplyDelete
    Replies
    1. Chu, I'm getting the same error, did you guys solved this problem?

      Delete
  52. same problem as chu said .. .. plz tell me what is the problem..

    ReplyDelete
  53. Hi Krams,

    Very good post, it was really usefull and is working fine in tomcat:run, I have one question, when i deployed the war file in jboss5.1 it thrown error message as

    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/hibernate-context.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: java.lang.NoSuchMethodException: org.hibernate.validator.ClassValidator.(java.lang.Class, java.util.ResourceBundle, org.hibernate.validator.MessageInterpolator, java.util.Map, org.hibernate.annotations.common.reflection.ReflectionManager)

    Do you have any idea what changes to be done in order to work in jboss5.1 version?

    Thanks in advance.

    Santosh

    ReplyDelete
  54. Hi Krams,
    Your Example is very good. It help a lot to start in Spring-Hibernate.

    One Problem I am facing is on running mvn:tomcat run my data in mysql tables get's deleted.

    So, I had to insert data every time I restart the application.

    Kindly provide some suggestion.

    Thanks in Advance.

    ReplyDelete
  55. @admin, this is because in hibernate.cfg.xml, the hbm2ddl.auto property is set to "create". You have to change that if you don't want that behavior. By the way, this is intentional since this is meant to be a tutorial.

    ReplyDelete
  56. @admin, i developed my own login application in spring framework, i checked a lot. but i am getting only 404-error(the requested resource is not available)in tomcat server.
    Plz help me is there any reason other than web.xml file configuration
    I configured successfully.

    Thanks for ur reply

    ReplyDelete
  57. @Unknown, did you check the logs for any specific errors? It's hard to troubleshoot if we can't see the logs. For the login, instead of creating your own, is it possible if you use Spring Security instead?

    ReplyDelete
  58. @Unknown, take a look at the following for Spring Security 3.1 http://krams915.blogspot.com/2012/01/spring-security-31-implement_5023.html

    ReplyDelete
  59. Hello @K Rams, its really such a nice tutorial for beginnaers, wanna ask u one q'n

    In my maven project i want to keep my .properties file out side the resource folder(src) there by when i make a jac of it, my .properties file will nt be included !!! so how can i do this ?
    i tried so many

    (bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer")
    (property name="location") <value)file:${config.files.dir}/info/Configuration.properties
    </value) </property) </bean)
    (bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer")
    (property name="location") <value)classpath:/info/Configuration.properties
    </value) </property) </bean)

    i am getting could nt find, nested exception, please help how to give that classpath

    ReplyDelete
  60. Hi,
    Can u list out the required jar files for this project

    ReplyDelete
  61. @Anonymous, take a look at the pom.xml file. This is a Maven project so all major dependencies are listed on that file. The sub-dependent jars are automatically pulled.

    ReplyDelete
  62. This is a simple yet practical introduction to Spring MVC and its integration with Hibernate. Thanks for providing a real code example rather than para upon para of theory!

    ReplyDelete
  63. this is an error in your code: Why would you have to call this: Person existingPerson = (Person) session.get(Person.class, person.getId());?

    public void edit(Person person) {
    logger.debug("Editing existing person");

    // Retrieve session from Hibernate
    Session session = sessionFactory.getCurrentSession();

    // Retrieve existing person via id
    Person existingPerson = (Person) session.get(Person.class, person.getId());

    // Assign updated values to this person
    existingPerson.setFirstName(person.getFirstName());
    existingPerson.setLastName(existingPerson.getLastName());
    existingPerson.setMoney(existingPerson.getMoney());

    // Save updates
    session.save(existingPerson);
    }

    can you just simply put one line in the method? it would work fine.
    sessionFactory.getCurrentSession().update(person);

    ReplyDelete
  64. @Can Lu, what is the error? You said there is an error but you didn't state what that error is.

    ReplyDelete
  65. Hi Krams i have created new dynamic web project and added your src folder and web/inf folder in my project .i have changed everything according to my package.i added all required jar files also,but i am getting this exception ,please help me to get out of this exception.

    : Error creating bean with name 'mainController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService': Injection of resource dependencies failed; nested exception is java.lang.NoClassDefFoundError: Ljavax/transaction/TransactionManager;

    ReplyDelete
  66. HI krams your application is working like charm,i have dont it atlast
    thanks for your great tutorial.

    ReplyDelete
  67. Hi Krams please can you tell me how you mapped /krams/main/persons to the personspage.jsp..??
    Im trying to do my own project from this tutorial but im not what to put in the URL to get my page up..

    ReplyDelete
  68. @Anonymous, the root mapping is found on the web.xml. That's where the /krams part is declared. The main/persons is declared in the MainController. At the class level you have

    @RequestMapping("/main"),

    then at the method level you have the

    @RequestMapping(value = "/persons", method = RequestMethod.GET)

    ReplyDelete
  69. this is my spring-security.xml

    ReplyDelete
  70. Thank you so much for your prompt replies and really informative tutorials...it's sites like this that makes the web a great place..

    ReplyDelete
  71. Thanks a lot for the great tutorial!

    There are so many similar blogs but most of the downloadable code samples are broken or add way too much complexity to begin with. This one is neat and clean and runs very well on GlassFish!

    Thanks, once again!

    ReplyDelete
  72. @Arun, thanks for the comment. I haven't tried this project on GlassFish. I would like to share the credit to the Spring and Hibernate guys though :-)

    ReplyDelete
  73. Great tutorial. Thank you.

    ReplyDelete
  74. Great work, can you please tell how the mapping to the JSP is done...its not very clear to me. thanks

    ReplyDelete
  75. Great example, worked like a charm, thank you krams!

    ReplyDelete
  76. I am not able to open it in net beans can you guide me

    ReplyDelete
  77. Hi Krams,

    Great tutorial! I was wondering how the data will be saved if I remove the "create" property in the hibernate.cfg.xml file? How would I go about it if I wanted to make a regular backup of my database in a human readable form?
    Thanks a million!

    All the best,
    David

    ReplyDelete
  78. Thanks for sharing your info. I really appreciate your efforts and I will be waiting for your further write ups thanks once again.
    html5 video player

    ReplyDelete
  79. Hi Krams,

    Can any one help me out in this.

    i am getting the following error.
    i am running this in tomcat 6

    i build the project in maven. but not able to run this application.

    got the following errors in the console.


    INFO: Starting Servlet Engine: Apache Tomcat/6.0.35
    Apr 12, 2012 11:26:12 AM org.apache.catalina.core.StandardContext listenerStart
    SEVERE: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
    java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1680)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4149)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
    at org.apache.catalina.core.StandardService.start(StandardService.java:525)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
    Apr 12, 2012 11:26:12 AM org.apache.catalina.core.StandardContext listenerStart
    SEVERE: Skipped installing application listeners due to previous error(s)
    Apr 12, 2012 11:26:12 AM org.apache.catalina.core.StandardContext start
    SEVERE: Error listenerStart
    Apr 12, 2012 11:26:12 AM org.apache.catalina.core.StandardContext start
    SEVERE: Context [/spring-hibernate-mysql] startup failed due to previous errors
    Apr 12, 2012 11:26:12 AM org.apache.coyote.http11.Http11Protocol start
    INFO: Starting Coyote HTTP/1.1 on http-8080
    Apr 12, 2012 11:26:12 AM org.apache.jk.common.ChannelSocket init
    INFO: JK: ajp13 listening on /0.0.0.0:8009
    Apr 12, 2012 11:26:12 AM org.apache.jk.server.JkMain start
    INFO: Jk running ID=0 time=0/16 config=null
    Apr 12, 2012 11:26:12 AM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 364 ms

    ReplyDelete
    Replies
    1. Following this link: http://stackoverflow.com/questions/6210757/java-lang-classnotfoundexception-org-springframework-web-context-contextloaderl

      Hope that useful !!!

      Delete
  80. I receive below exception when i hit the url:http://localhost:8080/spring3Hibernate/krams/main/persons.htm

    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

    root cause

    java.lang.NullPointerException
    org.krams.tutorial.controller.MainController.getPersons(MainController.java:41)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    ReplyDelete
    Replies
    1. This reply might be too late, sorry. It states that line 41 of MainController throws a NullPointerException. Have you debugged the root cause of this?

      Delete
  81. Please get me out this from this exception

    ReplyDelete
  82. hi sir how can i add Declare a datasource folder.I didnt find any subfolder in the given structure.please provide the correct path.I hope you given reply with in few days

    ReplyDelete
    Replies
    1. Why do you need to declare a datasource folder? I think I'm confused by your question.

      Delete
  83. Krams,
    Great tutorial! I've been using Spring for a few years but now have to make it work with Hibernate. I was flopping around trying to make things work without really understanding what was needed. Your tutorial nicely explained it all.

    I did not use Maven and I used PostgreSQL instead of MySql. I only had to change the driver and dialect to get things to work after manually downloading the required jars.

    Thanks again for a really useful tutorial.

    -=beeky

    ReplyDelete
  84. Very nice tutorial.Thanks for sharing!!
    It took some time for me to get it running cause not all the jars were mentioned in pom.xml, that are required for this project. I dont know how pom.xml works, I just put required jars (that are mentioned in this file) in classpath.

    Nevertheless, great work... at the end it works and helps in learning!

    ReplyDelete
  85. Man You wrote a great tutorial keep up....
    It helped me a lot as I'm searching such type of really helping tutorial for a couple of days

    ReplyDelete
  86. Many happy comments here, but I can resist to add another one.

    THANKS FOR THIS FANTASTIC TUTORIAL !!!!!

    After 3 J2EE courses, 10 books and 100 articles, finally something useful to make useful things in real life.

    I have never understand why most teachers and book writers use SMALL ISOLATED ABSTRACT UNREAL SNIPPETS OF CODE and they rarely work on REAL WORLD BASIC TECHNIQUES you will need at any job !

    It's fantastic to learn how to inject dependences from a Minstrel to a Knight (really it is ?) but nobody will contract you for that !!!


    Keep up the good work !!

    P.Scout.

    ReplyDelete
  87. HI Krams.
    I got the foll Exception through this .
    Please help me out.

    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from relative location [hibernate-context.xml]
    Offending resource: ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/tx]
    Offending resource: ServletContext resource [/WEB-INF/hibernate-context.xml]

    Thanks in Advance
    hitu

    ReplyDelete
    Replies
    1. Same error here...did you get the solution...please share if you did, thanks in advance

      Delete
  88. getting the error..


    SEVERE: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
    java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1676)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:415)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:397)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4660)
    at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
    at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

    ReplyDelete
  89. After changing the string connection,
    app.jdbc.driverClassName=com.mysql.jdbc.Driver
    app.jdbc.url=jdbc:mysql://192.168.2.100/hibernate
    app.jdbc.username=hibernate
    app.jdbc.password=hibernate

    getting this error from command line "mvn tomcat:run" & eclipse Goals:tomcat:run
    [ERROR] [main 08:28:27] (JDBCExceptionReporter.java:logExceptions:101) Connections could not be acquired from the underlying database!
    [ERROR] [main 08:28:47] (SchemaExport.java:execute:274) schema export unsuccessful
    java.sql.SQLException: Connections could not be acquired from the underlying database!
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)

    Could you please assist me why this happened, I use an other jave connection to oracle and mysql test program, they both working fine with the same connection string.

    Thanks in advance,

    Frank

    ReplyDelete
  90. Hi Krams,

    I am new in java web programming. So it's better for me learning by source code, then I could debug-trace flow of program. Your tutorial is very helpfull.

    Could you elaborate this tutorial with sitemesh. (Designing header and footer) in this project. Because many of us use header footer template to desaign web site.

    Thanks

    ReplyDelete
    Replies
    1. I haven't used SiteMesh but the idea should be similar with the Apache Tiles more or less. Check one of my guides with Apache Tiles.

      Delete
  91. sir,
    pls tell how to change Projectname from "spring-hibernate-mysql" to "MyProjectName"

    ReplyDelete
    Replies
    1. It's in the pom.xml. Find the name "spring-hibernate-mysql" and change it to "MyProjectName".

      If you're going to rename the folder itself, make sure to show all hidden files. Eclipse has hidden files and you have to edit those and replace the names as well.

      Delete
  92. Kram, would you please reply to this issue:
    SEVERE: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
    java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

    ReplyDelete
    Replies
    1. This issue is too vague. Is it possible if you paste the whole error using pastebin.com and give the URL here?

      Delete
  93. U rock .... gr8 stuff...
    Thanks
    After trying all things from web to run example for spring, hibernate and mysql ...couldn't run it ...spend almost 1 day ....

    but ur example run without doing anything .... great ..thanks once again ....

    ReplyDelete
  94. If you are having problems connecting like:
    [ERROR] [main 05:49:10] (JDBCExceptionReporter.java:logExceptions:101) Connections could not be acquired from the underlying database!

    Then maybe you have to create the database or set the port for your db.

    app.jdbc.url=jdbc:mysql://127.0.0.1:3306/mydatabase

    % mysql -u root -p
    > create database mydatabase

    ReplyDelete
    Replies
    1. Hi BOB,
      I too am facing the same issue of not connecting to the underlying database.

      While creating the DB(using linux mysql terminal) should I create the table PERSON too?

      Much appreciate your reply bob

      Delete
  95. Hi, i have this problem:

    set 20, 2012 3:43:12 PM org.apache.catalina.core.AprLifecycleListener init
    INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre7\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;.
    set 20, 2012 3:43:12 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
    WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:spring-hibernate-mysql' did not find a matching property.
    set 20, 2012 3:43:13 PM org.apache.coyote.http11.Http11Protocol init
    INFO: Initializing Coyote HTTP/1.1 on http-8080
    set 20, 2012 3:43:13 PM org.apache.catalina.startup.Catalina load
    INFO: Initialization processed in 847 ms
    set 20, 2012 3:43:13 PM org.apache.catalina.core.StandardService start
    INFO: Starting service Catalina
    set 20, 2012 3:43:13 PM org.apache.catalina.core.StandardEngine start
    INFO: Starting Servlet Engine: Apache Tomcat/6.0.35
    set 20, 2012 3:43:13 PM org.apache.catalina.core.StandardContext listenerStart
    SEVERE: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
    java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1680)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4149)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
    at org.apache.catalina.core.StandardService.start(StandardService.java:525)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)

    set 20, 2012 3:43:13 PM org.apache.catalina.core.StandardContext listenerStart
    SEVERE: Skipped installing application listeners due to previous error(s)
    set 20, 2012 3:43:13 PM org.apache.catalina.core.StandardContext start
    SEVERE: Error listenerStart
    set 20, 2012 3:43:13 PM org.apache.catalina.core.StandardContext start
    SEVERE: Context [/spring-hibernate-mysql] startup failed due to previous errors
    set 20, 2012 3:43:13 PM org.apache.coyote.http11.Http11Protocol start
    INFO: Starting Coyote HTTP/1.1 on http-8080
    set 20, 2012 3:43:13 PM org.apache.jk.common.ChannelSocket init
    INFO: JK: ajp13 listening on /0.0.0.0:8009
    set 20, 2012 3:43:13 PM org.apache.jk.server.JkMain start
    INFO: Jk running ID=0 time=0/47 config=null
    set 20, 2012 3:43:13 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 456 ms

    ReplyDelete
  96. This comment has been removed by the author.

    ReplyDelete
  97. Hi All,

    I like this tutorial ... i downloaded spring-hibernate-mysql.zip and import to Eclipse, i add all lib request, and then run it, No any error !!!

    But i didn't get any result, ==> http://localhost:8080/spring-hibernate-mysql/

    type Status report

    message /spring-hibernate-mysql/

    description The requested resource is not available.

    ===Q: What wrong with me please ?!!!

    ReplyDelete
  98. I agree,Boutxayayavong Phetsamone....I built successfuly with maven on tomcat..however,it gives 404 error :(

    I hope someone helps about it..

    ReplyDelete
  99. - open command line tool
    - set the directory to the directory of the project
    - enter mvn tomcat:run
    that's all...it works without any problem ;)

    To run on eclipse,it seems you need to make some configurations :l

    ReplyDelete
  100. find same error in all project...plz tell me that its is due to jar file or other error..thanx.


    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.mchange.v2.c3p0.ComboPooledDataSource] for bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/hibernate-context.xml]; nested exception is java.lang.ClassNotFoundException: com.mchange.v2.c3p0.ComboPooledDataSource

    ReplyDelete
  101. After looking at various examples I finally found one that is the BEST! Very well done, thanks for sharing my friend, can't thank enough.

    ReplyDelete
  102. hai all my brother and sister,
    please help me!!

    my self is very cofusing,2 day i can't succes.when running project like this WARNING:

    [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:spring-hibernate-many-to-one-jointable' did not find a matching property.

    in eclipse and tomcat 7 ,could help me? please my self newbe but i want to can running in eclipse and tomcat 7

    thank you

    ReplyDelete
  103. please help me,,,,,

    could give me step by step how is open in eclipse and tomcat 7...
    spring-hibernate-many-to-one-jointable

    thank you for all the my brother

    ReplyDelete
  104. Hi Kram,
    It was a good tutorial.
    Thanks..
    I am new to Spring as well as Hibernate. I successfully did this tutorial.And also checked "http://localhost:8080/spring-hibernate-mysql/krams/main/persons" and worked well. But by default when I run it in tomcat the address is "http://localhost:8080/spring-hibernate-mysql/", so I have to manually type the remaining part. How to redirect automatically to a desired HOMEPAGE??

    ReplyDelete
  105. Hi Kram,

    Thanks for the tutorial. I tried to run the application and is ending up with the following error
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'sessionFactory' is defined
    I have added jta.jar, hibernate-ehcache jar , still the error persists. could you also provide the list of jars needed to sun this app

    Thanks,
    Aruna

    ReplyDelete
  106. Greta tutorial...absolutely helpful for a beginner like me. worked like a charm

    ReplyDelete
  107. Works great !

    1. imported project into eclipse,
    2. edited db properties (spring.properties)
    3. mvn clean package
    4. mvn tomcat:run
    5. http://localhost:8080/spring-hibernate-mysql/krams/main/persons

    ReplyDelete
  108. Hello can someone repeat this tutorial using Netbeans 7.x

    ReplyDelete
  109. the best Spring MVC Hibenate tutorial on the earth

    ReplyDelete
  110. hey Boutxayayavong Phetsamone ...
    you need to include /krams/main/persons to your url....

    ReplyDelete
  111. Thank you for a great tutorial...

    Could you please say a few words about the application architecture you're using here: Domain/Service/Controller? Why adopt this approach?

    JJ

    ReplyDelete
  112. Thanks for a tutorial
    But a have found some mistake:
    You say in the post
    existingPerson.setFirstName(person.getFirstName());
    existingPerson.setLastName(existingPerson.getLastName());
    existingPerson.setMoney(existingPerson.getMoney());

    instead
    existingPerson.setFirstName(person.getFirstName());
    existingPerson.setLastName(person.getLastName());
    existingPerson.setMoney(person.getMoney());

    so edit the person does not save lastName and money

    But in the zip file this is correct

    ReplyDelete
  113. Hi Kram,

    Thanks for the tutorial. I tried to use listbox dynamique in my application ,can you help me please,how to delare it and how to do the mapping wiith hibernate

    ReplyDelete
  114. Hi Kram,

    Thanks for the tutorial. I tried to insert arabic in the database ,but it insert like this ?????,can you give me the solution please

    ReplyDelete
  115. Thanks Kram, this is really great. I've had a read over the spring in action book but had a really hard time putting it all together in practice. This fills in some gaps and I really appreciate the effort you went through to write this.

    Jan

    ReplyDelete
  116. good job man, I run the example with informix and works very well.
    Thank you

    ReplyDelete
  117. hi krams
    I need how two dynamic linked lists;please please help me

    ReplyDelete
  118. Hi Krams
    I have worked follow this tutorial , but i have a problem with save data to DB and start server(tomcat)
    when i save persons to DB , it work very good (person had been save to DB) . but when i stop server and check data in DB then DB is empty .
    If you known this issue , please tell me why ?

    ReplyDelete
  119. Very helpful tutorial. Thanks.

    ReplyDelete
  120. Thank you so much. this is wonderful.

    ReplyDelete
  121. wow!! it's really really coooooooooool.
    i have been learned spring by 24hour before.
    i love ur source. i respect u:)
    see ya~

    ReplyDelete
  122. awesome post it is very informative post.This tutorial it's very helpful.Thanks for the sharing

    ReplyDelete