Spring MVC + Hibernate + MySQL Quick Start From Scratch

This is a tutorial to build a very simple pizzashop Spring MVC, Hibernate and MySQL application. The main page shows all pizza rows stored on a database table:

03

Technology in Java world moves very fast. Using straight Hibernate might no longer be preferable since Java EE 5 introduces JPA (Java Persistence API) but it’s still good to learn anyway. Spring MVC and Hibernate is one of the most popular Java libraries used out there.

Tools / Environment Required
If you’re just starting fresh and don’t have most of the tools below just install JDK, STS (Springsource Tools Suite) and MySQL server, everything else is bundled within them.

Project Setup and Boilerplate

  1. First, create new Maven project on STS. Skip archetype selection. Pick maven group id, artifact id and select packaging to war.01 02
  2. By default Maven will use JDK 1.5, re-configure it to use 1.6. Add following maven-compiler-plugin section to pom.xml under <pom> element. Ensure the change takes effect by updating maven project settings (right click on project -> Maven -> Update project…).
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.1</version>
          <configuration>
            <source>1.6</source>
            <target>1.6</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  3. Add Spring, Hibernate, Java EE and MySQL maven dependencies to pom.xml. Place following under <pom> element.
    <properties>
      <spring.version>3.2.3.RELEASE</spring.version>
      <hibernate.version>4.2.2.Final</hibernate.version>
    </properties>
    
    <dependencies>
      <!-- Spring -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.version}</version>
      </dependency>
      
      <!-- Hibernate -->
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
      </dependency>
      
      <!-- Java EE -->
      <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
      </dependency>
      
      <!-- Others -->
      <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
      </dependency>
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.25</version>
      </dependency>
      
    </dependencies>
    
  4. Create a web.xml descriptor file with Spring MVC servlet setup on it, place it on src/main/webapp/WEB-INF
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
      <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
       
      <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
      
    </web-app>
    
  5. Create src/main/webapp/WEB-INF/servlet-context.xml Spring bean config file for dispatcher servlet. We configure few important stuffs in here:
    <?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:mvc="http://www.springframework.org/schema/mvc" xmlns:beans="http://www.springframework.org/schema/beans"
      xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    
      <!-- Enable @Controller annotation support -->
      <mvc:annotation-driven />
    
      <!-- Map simple view name such as "test" into /WEB-INF/views/test.jsp -->
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
      </bean>
      
      <!-- Scan classpath for annotations (eg: @Service, @Repository etc) -->
      <context:component-scan base-package="com.gerrytan.pizzashop"/>
      
      <!-- JDBC Data Source. It is assumed you have MySQL running on localhost port 3306 with 
           username root and blank password. Change below if it's not the case -->
      <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/pizzashop"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
        <property name="validationQuery" value="SELECT 1"/>
      </bean>
      
      <!-- Hibernate Session Factory -->
      <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="packagesToScan">
          <array>
            <value>com.gerrytan.pizzashop</value>
          </array>
        </property>
        <property name="hibernateProperties">
          <value>
            hibernate.dialect=org.hibernate.dialect.MySQLDialect
          </value>
        </property>
      </bean>
      
      <!-- Hibernate Transaction Manager -->
      <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
      </bean>
      
      <!-- Activates annotation based transaction management -->
      <tx:annotation-driven transaction-manager="transactionManager"/>
    </beans>
    
    


The Business Functionality

  1. Now all the boilerplate code done, we can start coding the business functionality. For this simple app we will have a pizza database table with just id, name and price column. Create the Pizza entity class representing the table
    package com.gerrytan.pizzashop;
    // imports ..
    
    @Entity
    @Table(name = "pizza")
    public class Pizza {
      @Id @GeneratedValue private long id;
      private String name;
      private double price;
      /* getters & setters */
    }
    
  2. Create a DAO class to obtain Pizza entity persisted on database. Note that we won’t create service layer classes for the sake of simplicity (on real-life complex business application adding service layer is a good practice).
    package com.gerrytan.pizzashop;
    // imports..
    
    @Repository
    @SuppressWarnings({"unchecked", "rawtypes"})
    public class PizzaDAO {
      @Autowired private SessionFactory sessionFactory;
      
      /**
       * @Transactional annotation below will trigger Spring Hibernate transaction manager to automatically create
       * a hibernate session. See src/main/webapp/WEB-INF/servlet-context.xml
       */
      @Transactional
      public List<Pizza> findAll() {
        Session session = sessionFactory.getCurrentSession();
        List pizzas = session.createQuery("from Pizza").list();
        return pizzas;
      }
    }
    
  3. Create a Spring MVC controller to handle request from the main page. Note that PizzaDAO reference is injected, and after collection of Pizza entity objects are obtained it’s passed to the view using Model object.
    package com.gerrytan.pizzashop;
    // imports..
    
    @Controller
    @RequestMapping("/")
    public class PizzaController {
      
      @Autowired private PizzaDAO pizzaDAO;
      
      /**
       * This handler method is invoked when
       * http://localhost:8080/pizzashop is requested.
       * The method returns view name "index"
       * which will be resolved into /WEB-INF/index.jsp.
       *  See src/main/webapp/WEB-INF/servlet-context.xml
       */
      @RequestMapping(method = RequestMethod.GET)
      public String list(Model model) {
        List<Pizza> pizzas = pizzaDAO.findAll();
        model.addAttribute("pizzas", pizzas);
        return "index";
      }
    }
    
  4. Add a JSP view to list all the pizza entities passed by the controller
    src/main/webapp/WEB-INF/index.jsp

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <!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=ISO-8859-1">
    <title>Pizzashop</title>
    </head>
    <body>
    	<h1>List of All Pizzas</h1>
    	<ul>
    		<c:forEach var="p" items="${pizzas}">
    			<li>${p.id} - ${p.name} - ${p.price}</li>
    		</c:forEach>
    	</ul>
    </body>
    </html>
    
  5. And finally prepare MySQL pizzashop database schema:
    CREATE SCHEMA `pizzashop`;

    And pizza table:

    CREATE  TABLE `pizzashop`.`pizza` (
      `id` BIGINT NOT NULL AUTO_INCREMENT ,
      `name` VARCHAR(45) NULL ,
      `price` DOUBLE NULL ,
      PRIMARY KEY (`id`) );
    

    And insert some data into it

    INSERT INTO `pizzashop`.`pizza` (`id`, `name`, `price`) VALUES ('I', 'Italian', '7.5');
    INSERT INTO `pizzashop`.`pizza` (`id`, `name`, `price`) VALUES ('2', 'Thin Crust', '6');
    INSERT INTO `pizzashop`.`pizza` (`id`, `name`, `price`) VALUES ('3', 'Pepperoni', '6.2');
    

    It is assumed you have MySQL server running on your local machine (localhost) on the default port 3306. The name of the schema is pizzashop and table pizza. Have a look at Spring beans configuration section above to reconfigure this.

Running The Code

  1. The easiest way to run your code is using in-memory Maven Tomcat plugin. It will launch on-the-fly Tomcat server with your code deployed. Make sure your project is selected on the project exploded and setup a maven run configuration on STS. Go to Run -> Run Configurations.. and create a new maven build entry like this:
    maven goal
  2. Click Run and navigate your browser to http://localhost:8080/pizzashop

Download The Source Code

Source code for this demonstration can be obtained using git:

git clone https://bitbucket.org/gerrytan/pizzashop.git -b basic

Congratz!

Well done on making it this far. Hopefully that was a quick and nice introduction to Spring MVC + Hibernate + MySQL and you can see how the tedious database to java class mapping is now simplified. You might have lots of questions in your mind by now — feel free to ask in the comment section below. Following are few official references and community article links you can browse around:

Also checkout my next tutorial about Hibernate One To Many Entity Relationship.

Advertisements

10 thoughts on “Spring MVC + Hibernate + MySQL Quick Start From Scratch

  1. good tutorial bro, but why i got and error after improve your code with service layer. before i added service layer your code worked perfectly

    org.springframework.beans.factory.BeanCreationException:

    • org.springframework.beans.factory.BeanCreationException can be caused by many things. You need to look further up what’s causing this. Common causes are failed autowiring, null pointer reference, etc.

  2. Hi, I’m having a little problem getting the app to run. Can you please offer any insights?

    The error I keep getting is…

    No plugin found for prefix ‘org.apache.tomcat.maven.tomcat7-maven-plugin’ in the current project and in the plugin groups …

    I still get the error after adding the plugin to the pom.xml build plugins element like this:

    org.apache.tomcat.maven
    tomcat7-maven-plugin
    2.2

    Thanks!

    • This is most likely because your maven is setup not to look for unknown plugin directly from central, eg: you have an internal company maven repository proxy. Have a look at your ~/.m2/repository and check if your maven is using any mirror, and ensure tomcat7 plugin is available on the mirror / use another mirror. Stack overflow has a lost of question posted about this problem

  3. I got this to work, however, after looking at the source code provided I noticed a ‘Topping’ class/table that is not talked about in this tutorial and I’d like to add that to my ‘pizzashop’ project.

    Is there a followup to this tutorial that adds additional functionality?

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s