Persist Java Object in MySQL Database With Hibernate

Hibernate is a great framework to use to persist data into a database when building RESTful Web Services for your mobile application with Jersey and JAX-RS. In most of the projects I have participated when designing RESTful Web Services for Mobile App we used MySQL database server and Hibernate framework to store user data which is encapsulated in Plain Old Java Objects.

In the example below I am going to share with you how to store some data that was sent via HTTP POST Request as a JSON Payload from Mobile Application to our RESTful Web Service which is built with Jersey and JAX-RS. We will go step by step and will cover following:

  1. Use Maven to create Java Web App
  2. Add Jersey, MySQL, Spring and Hibernate framework dependencies into our project
  3. Configure our project to work with Hibernate by creating a hibernate.cfg.xml file
  4. Create JAX-RS Application Starting Point class
  5. Create Java object to convert the JSON Payload into
  6. Create Hibernate Utils class which will be responsible for creating a Hibernate Session Factory object
  7. Create Hibernate Entity Java class which will be stored in MySQL Database
  8. Create MySQL Data Access Object which will be used to take the Entity object and store it in MySQL database
  9. Create Service Layer Interface and Service Layer Interface Implementation
  10. Create Root Resource and a RESTful Web Service End Point

Also, all of these steps are being explained and demonstrated in video lessons in my video course: REST API with Java JAX-RS. Create and Deploy to Amazon Cloud.

Project Structure

At the end of this tutorial my project structure looks like the one on the picture below. Each class I am creating in this example, I put in a specific Java package depending on which layer this class belongs to. There are three main levels I have organized this example into:

  • UI level. This is were my Root Resource Class is and this is where Web Service Endpoints are defined, HTTP Requests are received and HTTP Responses are being prepared,
  • Service Layer. This is where all the main business logic is taking place,
  • Data Layer.  This is where I encapsulate code that deals with Database communication.

Here is how my project package structure looks like:

Save Java Object into MySQL with Hibernate

Create Java Web Application with Maven

Earlier I have published a very short tutorial on how to create and run a very simple Java Web Application with Maven. Please follow this link to learn how to use Maven to quickly create simple Java Web Application.

Add Jersey, MySQL, Spring Framework and Hibernate Dependencies to pom.xml

The below pom.xml file contains the needed dependencies to support our goal in this project which is to Build RESTFul Web Service to store user data into MySQL Database using Hibernate framework. Each dependency added to a pom.xml file has a url to a Maven repository page which contains the dependency XML. You can open those URLs in the browser window and browse Maven repository web page to look for newer or may be even earlier versions of these dependencies.

You can find pom.xml file in your project files if you created this project with Maven.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.appsdeveloperblog.ws</groupId>
    <artifactId>HibernateExamples</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>HibernateExamples Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.bundles/jaxrs-ri -->
        <dependency>
            <groupId>org.glassfish.jersey.bundles</groupId>
            <artifactId>jaxrs-ri</artifactId>
            <version>2.25</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-moxy -->
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>2.25</version>
        </dependency>
        
   <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-moxy -->
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>2.25</version>
        </dependency>
    
        <!-- Hibernate Dependencies -->
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.8.Final</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.0.Final</version>
        </dependency>
        
        <!-- MySQL Dependencies -->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.41</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.1.Final</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>HibernateExamples</finalName>
    </build>
</project>

Create hibernate.cfg.xml File

My project name is HibernateExamples and I have created my hibernate.cfg.xml in /src/main/resources/hibernate.cfg.xml. This file contains information needed for Hibernate to store data into a MySQL database server. For example in contains:

  • hibernate.connection.driver_class – which specifies which driver is being used to store data into a database
  • hibernate.connection.url – which contains the host, port number and the database name which is being used to store the data
  • hibernate.connection.username – user name which is being used to connect to a MySQL database
  • hibernate.connection.password – user password which is being used to connect to MySQL database
  • and hibernate.hbm2ddl.auto which is good to have if we do not want our database scheme to be re-created every time. Remember that with hibernate we do not create database tables ourselves. Hibernate framework does it for us. If database table does not exists, it will be created when we attempt to persist an Entity java class
<?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">
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

Copyright (c) 2008, 2016 Oracle and/or its affiliates. All rights reserved.

Oracle and Java are registered trademarks of Oracle and/or its affiliates.
Other names may be trademarks of their respective owners.

The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://www.netbeans.org/cddl-gplv2.html
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
specific language governing permissions and limitations under the
License.  When distributing the software, include this License Header
Notice in each file and include the License file at
nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
particular file as subject to the "Classpath" exception as provided
by Oracle in the GPL Version 2 section of the License file that
accompanied this code. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"

If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 2, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 2] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 2 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 2 code and therefore, elected the GPL
Version 2 license, then the option applies only if the new code is
made subject to such option by the copyright holder.

Contributor(s):
-->
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/photo_app?zeroDateTimeBehavior=convertToNull</property>
        <property name="hibernate.connection.username">sergey</property>
        <property name="hibernate.connection.password">sergey</property>
        
        <property name="hibernate.id.new_generator_mappings">true</property>  
        <property name="show_sql">true</property> 
        <property name="connection.pool_size">10</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
 
    </session-factory>
</hibernate-configuration>

Create JAX-RS Application Starting Point Class

With this Java class we are going to create we will define the base URI for all resource URIs. This base URI will be a prefix to all of our web services end points. Because I am creating an API for my mobile application I will create the base URI for my web services as “api”. Now, when I create a new Web Service Endpoint and give it a name “users” I will need to access it using the /api/users. If this class defines application path as “my-api” then, I will be able to access my newly created Web Service Endpoint with a name users like this: /my-api/users. You get the idea.

package com.appsdeveloperblog.ws;

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
 
@ApplicationPath("api")
public class MyApi extends ResourceConfig {
 
}

Create Java object to convert the JSON Payload Into

When Mobile Application Submits HTTP POST Request containing JSON Payload in HTTP Request Body, our web service end point will accept this HTTP Request and the JSON Payload will be converted into a Java object. The fields in this Java class that we need to create must should match the keys in JSON Payload. If JSON Payload has more or has different keys than our Java class defines, then JAX-RS will not be able to convert this JSON Payload into a Java object and an error message will be generated. Below is the JSON Payload that our Web Service will be expecting and the Java class into which this JSON Payload will be converted.

JSON Payload

{
 "firstName":"Sergey",
 "lastName":"Kargopolov"
}

Java Class the above JSON Payload will be converted into

package com.appsdeveloperblog.ws.ui.rest;

import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement
public class UserProfile {
    private String firstName;
    private String lastName;

    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }

    /**
     * @param firstName the firstName to set
     */
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * @return the lastName
     */
    public String getLastName() {
        return lastName;
    }

    /**
     * @param lastName the lastName to set
     */
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

Hibernate SessionFactory

To persist Java object in a MySQL Database, Hibernate will need to establish a session with the database. The code that creates a SessionFactory which can then be used to open and close database sessions I am putting into a new Java class with a name HibernateUtils.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appsdeveloeperblog.ws.utils;
 

import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
 
public class HibernateUtils {
     
    private static final SessionFactory sessionFactory;
     
    static {
        Configuration conf = new Configuration();
        conf.configure();
 
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (HibernateException e) {
            System.err.println("Initial SessionFactory creation failed." + e);
            throw new ExceptionInInitializerError(e);
        }       
    }
     
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
} 

Create Hibernate Entity Java class which will be stored in MySQL Database

The JSON Payload which our Web Service will receive, will be converted into UserProfile Plain Java Object. But this object as is cannot be used to be persisted in MySQL Database with Hibernate framework. Hibernate framework uses Java objects which are annotated with some special annotations. Let’s create a new Java class and annotated with the following:

  • @Id and @GeneratedValueTo specify that this field is an id and that it’s value should be auto generated.
  • @Entity(name=”Profile”) to specify how we want the database table name to be called if it is not created and when the database table is created this name will be used to identify which database table should be used to persist the information from our entity object.
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appsdeveloperblog.ws.io.entity;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 *
 * @author skargopolov
 */
@Entity(name="Profile")
public class UserProfileEntity implements Serializable {
    
    private static final long serialVersionUID = 7290798953394355234L;
    
    @Id
    @GeneratedValue
    private long id;
    private String firstName;
    private String lastName;

    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }

    /**
     * @param firstName the firstName to set
     */
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * @return the lastName
     */
    public String getLastName() {
        return lastName;
    }

    /**
     * @param lastName the lastName to set
     */
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    /**
     * @return the id
     */
    public long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }
}

Create MySQL Data Access Object

The below interface and the implementation of this interface classed are needed to encapsulate all business logic which has to do with writing into a database and reading from a database table. It is good to encapsulate all these functionality into a separate class which will help us maintain the code of our application and have it well organized.

Database interface

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appsdeveloperblog.ws.io.dao;

import com.appsdeveloperblog.ws.io.entity.UserProfileEntity;

/**
 *
 * @author skargopolov
 */
public interface Database {
    public void openConnection();
    public UserProfileEntity saveUserProfile(UserProfileEntity userProfile);
    public void closeConnection();
}

MySQL Data Access Object. Database Interface Implementation Class

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appsdeveloperblog.ws.io.dao.impl;

import com.appsdeveloeperblog.ws.utils.HibernateUtils;
import com.appsdeveloperblog.ws.io.dao.Database;
import com.appsdeveloperblog.ws.io.entity.UserProfileEntity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

/**
 *
 * @author skargopolov
 */
public class MySQLDAO implements Database {

    Session session;

    public void openConnection() {
        SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
        this.session = sessionFactory.openSession();
    }

    public UserProfileEntity saveUserProfile(UserProfileEntity userProfile) {

        this.session.beginTransaction();
        this.session.save(userProfile);
        this.session.getTransaction().commit();

        return userProfile;
    }

    public void closeConnection() {
        this.session.close();
    }
}

Service Layer Interface and Service Layer Interface Implementation

Your Web Service might have a lot of business logic to do and it is good to take all that large and complex business logic and organize it in a separate class. This class will be the Service layer of our application and service layer class will be responsible for taking data from a Web Service, then do all the necessary business logic and when done pass it over to a MySQL Data Access object so it can store the data into a database.

Service layer Interface

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appsdeveloperblog.ws.service;

import com.appsdeveloperblog.ws.shared.dto.UserProfileDto;

/**
 *
 * @author skargopolov
 */
public interface UsersService {
    public UserProfileDto saveUser(UserProfileDto user);
}

Service Layer Interface Implementation Class

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appsdeveloperblog.ws.service.impl;

import com.appsdeveloperblog.ws.io.dao.Database;
import com.appsdeveloperblog.ws.io.entity.UserProfileEntity;
import com.appsdeveloperblog.ws.service.UsersService;
import com.appsdeveloperblog.ws.shared.dto.UserProfileDto;
import org.springframework.beans.BeanUtils;

/**
 *
 * @author skargopolov
 */
public class UsersServiceImpl implements UsersService {

    Database database;

    public UserProfileDto saveUser(UserProfileDto userDto) {
        
        UserProfileDto returnValue = null;
        
        UserProfileEntity userEntity = new UserProfileEntity();
        BeanUtils.copyProperties(userDto, userEntity);
        
        // Connect to database 
        try {
            this.database.openConnection();
            UserProfileEntity storedUserEntity = this.database.saveUserProfile(userEntity);
            if(storedUserEntity != null && storedUserEntity.getId()>0)
            {
                returnValue = new UserProfileDto();
                BeanUtils.copyProperties(storedUserEntity, returnValue);
            }
        }  finally {
            this.database.closeConnection();
        }
        
        return returnValue;
    }

}

RESTful Web Service Root Resource Class

And finally we need to create the Root Resource class of our Web Service. This class will define one method which will access as an argument the UserProfile class into which the JSON Payload sent via HTTP Post Request will be converted.

This method will then pass the UserProfile details into a Service layer using the User Profile Data Transfer Object, Service Layer will pass it on to a Data layer in a form on Entity Object and MySQL Data Access Object will store the data into a database.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appsdeveloperblog.ws.entrypoints;

import com.appsdeveloperblog.ws.service.UsersService;
import com.appsdeveloperblog.ws.service.impl.UsersServiceImpl;
import com.appsdeveloperblog.ws.shared.dto.UserProfileDto;
import com.appsdeveloperblog.ws.ui.rest.UserProfile;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.springframework.beans.BeanUtils;

/**
 *
 * @author skargopolov
 */
@Path("/users")
public class Users {
    
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public UserProfile createUserProfile(UserProfile userProfile) {

        UserProfile returnValue = null;
        
        UserProfileDto userProfileDto = new UserProfileDto();
        BeanUtils.copyProperties(userProfile, userProfileDto);
        
        UsersService usersService = new UsersServiceImpl();
        UserProfileDto storedUserDetails = usersService.saveUser(userProfileDto);
         
        if(storedUserDetails != null && !storedUserDetails.getFirstName().isEmpty())
        {
            returnValue = new UserProfile();
            BeanUtils.copyProperties(storedUserDetails, returnValue);
        }

       // And when we are done, we can return user profile back
        return userProfile;
    }
    
}

If have challenges with any of these code examples, you can follow video lessons instead. All the the above steps I have recorded on video and made it part of my video course:  REST API with Java JAX-RS. Create and Deploy to Amazon Cloud.

Download Complete Source Code in Netbeans Project

You can copy and paste my code from this page or you can download entire Netbeans project. But before running it, please make sure you update the hibernate.cfg.xml with the user name and password as well as database name that you use.

Send HTTP POST Example in Swift

The below code example demonstrates how to send HTTP POST request with the two Request Parameters which the above Web Service End Point we have created can accept. These two request parameters will be sent as a JSON Payload which we have also discussed in the beginning of this blog post.

let myUrl = URL(string: "https://www.appsdeveloperblog.com/api/users");
       
       var request = URLRequest(url:myUrl!)
       
       request.httpMethod = "POST"// Compose a query string
       
       let postString = "firstName=James&lastName=Bond";
       
       request.httpBody = postString.data(using: String.Encoding.utf8);
       
       let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
           
           if error != nil
           {
               print("error=\(error)")
               return
           }
           
           // You can print out response object
           print("response = \(response)")
  
           //Let's convert response sent from a server side script to a NSDictionary object:
           do {
               let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
               
               if let parseJSON = json {
                   
                   // Now we can access value of First Name by its key
                   let firstNameValue = parseJSON["firstName"] as? String
                   print("firstNameValue: \(firstNameValue)")
               }
           } catch {
               print(error)
           }
       }
       task.resume()

For more ready to use Code Examples in Swift checkout this page http://swiftdeveloperblog.com/code-examples/

Video Courses

If you are looking for a step by step video instructions on how to create Restful Web Services with Java checkout out the below video courses:

Java Web Services Part 1. Video Course.

Java icon

Java Web Services Part 2. Video Course.

Master advanced web services concepts and implement them in easy steps Java Web Services Part 2 icon

REST Java Web Services. Video Course.

A guide to understanding, accessing, and writing a REST Java web service using Apache and Java EE. Java Web Services Part 2 icon


Leave a Reply

Your email address will not be published. Required fields are marked *