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:
- Use Maven to create Java Web App
- Add Jersey, MySQL, Spring and Hibernate framework dependencies into our project
- Configure our project to work with Hibernate by creating a hibernate.cfg.xml file
- Create JAX-RS Application Starting Point class
- Create Java object to convert the JSON Payload into
- Create Hibernate Utils class which will be responsible for creating a Hibernate Session Factory object
- Create Hibernate Entity Java class which will be stored in MySQL Database
- Create MySQL Data Access Object which will be used to take the Entity object and store it in MySQL database
- Create Service Layer Interface and Service Layer Interface Implementation
- 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:
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 Web Services Part 2. Video Course.
Master advanced web services concepts and implement them in easy stepsREST Java Web Services. Video Course.
A guide to understanding, accessing, and writing a REST Java web service using Apache and Java EE.