Creating a CRUD REST API/Service with Spring Boot, JPA and Hibernate

Image Image

This guide will help you create a CRUD REST API/Service with Spring Boot, JPA and Hibernate. We will create a JPA Repository for a Student Entity and expose it using a Student Resource.

You will learn

  • What is a RESTful Service?
  • Basics of designing a REST API.
  • How to create a RESTful Service offering all CRUD operations?
  • How to use Spring Boot, Spring MVC, JPA and Hibernate to create a RESTful API?
  • How to execute different kinds of REST API with Postman?
  • What are the differences between GET, POST, PUT and DELETE request methods?

Free Courses - Learn in 10 Steps

Resources Overview

In this guide, we will create a Student Resource exposing three services using proper URIs and HTTP methods:

  • Retrieve all Students - @GetMapping(“/students”)
  • Get details of specific student - @GetMapping(“/students/{id}”)
  • Delete a student - @DeleteMapping(“/students/{id}”)
  • Create a new student - @PostMapping(“/students”)
  • Update student details - @PutMapping(“/students/{id}”)

Project Code Structure

Following screenshot shows the structure of the project we will create. Image

A few details:

  • - The Spring Boot Application class generated with Spring Initializer. This class acts as the launching point for application.
  • pom.xml - Contains all the dependencies needed to build this project. We will use Spring Boot Starter AOP.
  • - Student JPA Entity
  • - Student JPA Repository. This is created using Spring Data JpaRepository.
  • - Spring Rest Controller exposing all services on the student resource.
  • data.sql - Initial data for the student table. Spring Boot would execute this script after the tables are created from the entities.

Tools you will need

  • Maven 3.0+ is your build tool
  • Your favorite IDE. We use Eclipse.
  • JDK 1.8+

Complete Maven Project With Code Examples

Our Github repository has all the code examples -

Types of Web Services

Not really types but a broad classification

  • SOAP
  • REST

These are not really mutually exclusive. Some SOAP services can actually be RESTful.


First of all, REST does not define a standard message exchange format. You can build REST services with both XML and JSON. However, JSON is a more popular format with REST.

So, if it does not define a standard message exchange format, what is REST then?

REST is a style of software architecture for distributed hypermedia systems

REST stands for REpresentational State Transfer. The definitions for REST can be vague. So, lets understand the important concepts.

Key abstraction in REST is a Resource. There is no restriction on what can be a resource. A todo is a resource. A person on facebook is a resource.

A resource has an URI (Uniform Resource Identifier):

  • /user/Ranga/todos/1
  • /person/Ranga

A resource will have representations

  • XML
  • HTML
  • JSON

A resource will have state. The representation of a resource should capture its current state.

When a resource is requested, we provide the representation of the resource.


REST builds on top of HTTP (Hypertext Transfer Protocol). HTTP is the language of the web.

HTTP has a few important verbs.

  • POST - Create a new resource
  • GET - Read a resource
  • PUT - Update an existing resource
  • DELETE - Delete a resource

HTTP also defines standard response codes.

  • 200 - SUCESS
  • 400 - BAD REQUEST
  • 201 - CREATED
  • 415 - UNSUPPORTED TYPE - Representation not supported for the resource
  • 500 - SERVER ERROR

Restful Service Constraints

  • Client - Server : There should be a service producer and a service consumer.
  • The interface (URL) is uniform and exposing resources. Interface uses nouns (not actions)
  • The service is stateless. Even if the service is called 10 times, the result must be the same.
  • The service result should be Cacheable. HTTP cache, for example.
  • Service should assume a Layered architecture. Client should not assume direct connection to server - it might be getting info from a middle layer - cache.

Designing RESTful APIs

Following are the important things to consider when designing RESTful API’s:

  • While designing any API, the most important thing is to think about the api consumer i.e. the client who is going to use the service. What are his needs? Does the service uri make sense to him? Does the request, response format make sense to him?
  • In Rest, we think Nouns (resources) and NOT Verbs (NOT actions). So, URI’s should represent resources. URI’s should be hierarchical and as self descriptive as possible. Prefer plurals.
  • Always use HTTP Methods.
    • GET : Should not update anything. Should be idempotent (same result in multiple calls). Possible Return Codes 200 (OK) + 404 (NOT FOUND) +400 (BAD REQUEST)
    • POST : Should create new resource. Ideally return JSON with link to newly created resource. Same return codes as get possible. In addition : Return code 201 (CREATED) is possible.
    • PUT : Update a known resource. ex: update client details. Possible Return Codes : 200(OK)
    • DELETE : Used to delete a resource.

When do you use JPA?

  • SQL Database
  • Static Domain Model
  • Mostly CRUD
  • Mostly Simple Queries/Mappings

Bootstrapping with Spring Initializr

Creating a REST service with Spring Initializr is a cake walk. We will use Spring Web MVC as our web framework.

Spring Initializr is great tool to bootstrap your Spring Boot projects.



As shown in the image above, following steps have to be done

  • Launch Spring Initializr and choose the following
    • Choose as Group
    • Choose spring-boot-2-rest-service-basic as Artifact
    • Choose following dependencies
      • Web
      • JPA
      • H2
      • DevTools
      • TODO
  • Click Generate Project.
  • Import the project into Eclipse. File -> Import -> Existing Maven Project.

Do not forget to add JPA and H2 as dependencies.

Create Your First JPA Entity

The first step is to create a JPA Entity. Lets create a simple Student Entity with a primary key id.

public class Student {
	private Long id;
	private String name;
	private String passportNumber;

Important things to note:

  • @Entity: Specifies that the class is an entity. This annotation is applied to the entity class.
  • @Id: Specifies the primary key of an entity.
  • @GeneratedValue: Provides for the specification of generation strategies for the values of primary keys.
  • public Student(): Default constructor to make JPA Happy

When the application reloads, you can launch H2 console at http://localhost:8080/h2-console.

You will see that a new table called ‘student’ is created in H2 Console.

How did the Student table get created?

Spring Boot Auto Configuration detects that we are using an in-memory database H2. It autoconfigures the property to create the database tables based on the Entities.

Let’s now populate some data into the student table.


insert into student
values(10001,'Ranga', 'E1234567');

insert into student
values(10002,'Ravi', 'A1234568');

When the application reloads you would see following statements in the log indicating that the sql files are picked up.

Executing SQL script from URL [file:/in28Minutes/git/spring-boot-examples/spring-boot-2-jdbc-with-h2/target/classes/data.sql]

After App Reload, When you login to H2 Console (http://localhost:8080/h2-console) you can see that the student table is created and the data is populated.


Image Image Image



Create JPA Repository class to Read Student from Database


We create a simple interface StudentRepository extending JpaRepository.

public interface StudentRepository extends JpaRepository<Student, Long>{


  • We will talk about all the methods in the JpaRepository a little later.
  • public interface StudentRepository extends JpaRepository<Student, Long> - We are extending JpaRepository using two generics - Student & Long. Student is the entity that is being managed and the primary key of Student is Long.


JpaRepository (Defined in Spring Data JPA) is the JPA specific Repository interface.

public interface JpaRepository<T, ID extends Serializable>
		extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

JpaRepository extends PagingAndSortingRepository which in turn extends CrudRepository interface. So, JpaRepository inherits all the methods from the two interfaces shown below.


public abstract interface PagingAndSortingRepository extends CrudRepository {
  public abstract Iterable findAll(Sort arg0);
  public abstract Page findAll(Pageable arg0);



public interface CrudRepository<T, ID extends Serializable>
    extends Repository<T, ID> {

    <S extends T> S save(S entity);

    T findOne(ID primaryKey);       

    Iterable<T> findAll();          

    Long count();                   

    void delete(T entity);          

    boolean exists(ID primaryKey);  

    // … more functionality omitted.

Exposing Resources using StudentResource

Lets start with setting up the StudentResource class and then move into creating methods to handle different kinds of request methods to the Student Resouce.

Setting up Student Resource

public class StudentResource {

	private StudentRepository studentRepository;


  • @RestController : Combination of @Controller and @ResponseBody. Beans returned are converted to/from JSON/XML.
  • @Autowired private StudentRepository studentRepository : Autowire the StudentRepository so that we can retrieve and save data to database.

Exposing GET methods on Student Resource

Let’s create the method to expose the details of all students.

public List<Student> retrieveAllStudents() {
	return studentRepository.findAll();

Below picture shows how we can execute a Get Request Method on a Resource using Postman - my favorite tool to run rest services. Image

  • URL - http://localhost:8080/students
  • Request Method - GET


    "id": 10001,
    "name": "Ranga",
    "passportNumber": "E1234567"
    "id": 10002,
    "name": "Ravi",
    "passportNumber": "A1234568"

Let’s create a method to expose the details of a specific student.

public Student retrieveStudent(@PathVariable long id) {
	Optional<Student> student = studentRepository.findById(id);

	if (!student.isPresent())
		throw new StudentNotFoundException("id-" + id);

	return student.get();

Let’s execute another GET request Image

  • URL - http://localhost:8080/students/10002
  • Request Method - GET


  "id": 10002,
  "name": "Ravi",
  "passportNumber": "A1234568"

Expose DELETE Method on Student Resouce

Delete method is simple. All you have to do is to call studentRepository.deleteById(id).

public void deleteStudent(@PathVariable long id) {

Below picture shows how we can execute a DELETE Request method on a Resource from Postman - my favorite tool to run rest services. Image

  • URL - http://localhost:8080/students/10002
  • Request Method - DELETE

Request - Empty Body Response with status 200 - Successful

Expose POST Method to create a new student

POST method is simple. All you have to do is to call Note that we are using @RequestBody to map the student details from request to bean. We are also returning a ResponseEntity with a header containing the URL of the created resource.

public ResponseEntity<Object> createStudent(@RequestBody Student student) {
	Student savedStudent =;

	URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")

	return ResponseEntity.created(location).build();


Below picture shows how we can execute a POST Request method on a Resource from Postman - my favorite tool to run rest services. Image

  • URL - http://localhost:8080/students
  • Request Method - POST


    "name": "Tom",
    "passportNumber": "Z1234567"


  • Status 201 - CREATED
  • Header Location →http://localhost:8080/students/2

Expose PUT Method to update existing student

Before updating the student we check if the student exists. If the student does not exist, we return a not found statur. Otherwise, we save the student details using method.

public ResponseEntity<Object> updateStudent(@RequestBody Student student, @PathVariable long id) {

	Optional<Student> studentOptional = studentRepository.findById(id);

	if (!studentOptional.isPresent())
		return ResponseEntity.notFound().build();


	return ResponseEntity.noContent().build();

Below picture shows how we can execute a PUT Request method on a Resource from Postman - my favorite tool to run rest services. Image

  • URL → http://localhost:8080/students/10002
  • Request
    • Method → PUT


	"name": "Tom",
	"passportNumber": "Z1234567"

Response with status 200 - Successful

Remember that you can check the updates in the database using H2 Console http://localhost:8080/h2-console after each of the requests.

Complete Code Example

Github repository has all the code examples -

Best Selling Udemy Courses

Image Image Image Image Image Image Image Image Image Image Image Image

Join 450,000 Learners and 30+ Amazing Courses

350,000 Learners are learning everyday with our Best Selling Courses : Spring Boot Microservices, Spring, Spring Boot, Web Services, Hibernate, Full Stack React, Full Stack Angular, Python, Spring Interview Guide, Java Interview, Java Functional Programming, AWS, Docker, Kubernetes, PCF, AWS Fargate and Azure

Do not know where to start your learning journey? Check out our amazing learning paths:
Learning Path 01 - Spring and Spring Boot Web Applications and API Developer,
Learning Path 02 - Full Stack Developer with Spring Boot, React & Angular,
Learning Path 03 - Cloud Microservices Developer with Docker and Kubernetes,
Learning Path 04 - Learn Cloud with Spring Boot, AWS, Azure and PCF and
Learning Path 05 - Learn AWS with Microservices, Docker and Kubernetes



Related Posts

Understanding jwt token

Let us understand the json web tokens

Single sign-on workflow

Let us understand the single sign-on workflow

Oauth2.0 - Resource Owner Password Credentials grant workflow

Let us understand the Oauth2.0 Resource Owner Password Credentials grant workflow

Oauth2.0 - Implicit grant workflow

Let us understand the Oauth2.0 implicit grant workflow

Oauth2.0 - Client Credentials grant workflow

Let us understand the Oauth2.0 client credentials grant workflow

Oauth2.0 - Authorization grant workflow

Let us understand the Oauth2.0 authorization grant workflow

Writing Integration Tests for Rest Services with Spring Boot

Setting up a basic REST Service with Spring Boot is a cake walk. We will go one step further and add great integration tests!

Integrating Spring Boot and Spring JDBC with H2 and Starter JDBC

Learn using Spring Boot Starter JDBC to connect Spring Boot to H2 (in memory database) using Spring JDBC. You will create a simple project with Spring Boot. You will add code to the project to connect to a database using Spring JDBC. You will learn to implement the basic CRUD methods.

JUnit Tutorial for Beginners in 5 Steps

JUnit Tutorial for Beginners in 5 Steps. Setting up a basic JUnit example and understanding the basics of junit.

JPA and Hibernate Tutorial For Beginners - 10 Steps with Spring Boot and H2

JPA and Hibernate in 10 Steps with H2 - Setting up a basic project example with Spring Boot and in memory database H2. Its a cake walk.