DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Spring Boot - How To Use Native SQL Queries | Restful Web Services
  • RESTful Web Services: How To Create a Context Path for Spring Boot Application or Web Service
  • How To Validate HTTP Post Request Body - Restful Web Services With Spring Framework | Spring Boot
  • RESTful Web Services With Spring Boot: Reading HTTP POST Request Body

Trending

  • Start Coding With Google Cloud Workstations
  • Agentic AI for Automated Application Security and Vulnerability Management
  • Unlocking Data with Language: Real-World Applications of Text-to-SQL Interfaces
  • DGS GraphQL and Spring Boot
  1. DZone
  2. Coding
  3. Frameworks
  4. Build a RESTful CRUD Service With Spring Boot, Hibernate, and JPA

Build a RESTful CRUD Service With Spring Boot, Hibernate, and JPA

A complete guide to writing a RESTful CRUD service using Spring Boot, Hibernate, and JPA, as well as testing the using GET, DELETE, PUT, and POST calls.

By 
Amit Phaltankar user avatar
Amit Phaltankar
·
Feb. 10, 21 · Tutorial
Likes (6)
Comment
Save
Tweet
Share
20.0K Views

Join the DZone community and get the full member experience.

Join For Free

A CRUD REST service allows HTTP GET, POST, PUT, and DELETE endpoints on the underlying resource. A client can use these endpoints to Create, Read, Update, and Delete resources by providing respective resource identifiers. 

This tutorial gives a step-by-step way of building your own RESTful CRUD service in Spring Boot to perform CRUD operations on a database resource by using Spring Data JPA and Hibernate.

We will write a Students Service, which is an example of Spring Boot REST application. The service allows clients to add new students, find students, and modify or delete any existing students. On the backend we will use an H2 database to store students' information. 

In this tutorial, we will cover:

  1. The required POM Dependencies.
  2. How to create an Entity Class for Students.
  3. How to write a Spring Data Repository.
  4. How to write a REST Controller that has CRUD APIs.
  5. How to test our app.

Maven Dependencies

In order to run a basic Spring Boot JPA project we need web starter and data-jpa starter dependencies.

XML
 




x
20


 
1
    <dependencies>
2
        <dependency>
3
            <groupId>org.springframework.boot</groupId>
4
            <artifactId>spring-boot-starter-data-jpa</artifactId>
5
        </dependency>
6
        <dependency>
7
            <groupId>org.springframework.boot</groupId>
8
            <artifactId>spring-boot-starter-web</artifactId>
9
        </dependency>
10
        <dependency>
11
            <groupId>com.h2database</groupId>
12
            <artifactId>h2</artifactId>
13
            <scope>runtime</scope>
14
        </dependency>
15
        <dependency>
16
            <groupId>org.projectlombok</groupId>
17
            <artifactId>lombok</artifactId>
18
            <optional>true</optional>
19
        </dependency>
20
    </dependencies>


We have also added an H2 database dependency, which is a Java-based, in-memory database. Spring Boot, by default, connects to an H2 database, if the database is available on the class path. In other words, we do not need to provide any connection details for this database.

Write an Entity Bean

We will create a Student class that has an @Entity annotation, to make it an entity bean. Also, the student class has basic fields, where the Id is an autogenerated incremental field.

Java
 




x
16


 
1
package com.amitph.spring.tutorials.students.entity;
2
import lombok.Data;
3
import javax.persistence.Entity;
4
import javax.persistence.GeneratedValue;
5
import javax.persistence.GenerationType;
6
import javax.persistence.Id;
7
@Entity
8
@Data
9
public class Student {
10
    @Id
11
    @GeneratedValue(strategy = GenerationType.IDENTITY)
12
    private Long student_id;
13
    private String firstName;
14
    private String lastName;
15
    private int year;
16
}


We are using Lombok @Data annotations, which auto-generates all the getters and setters for this class.

Create JPA Repository

Next, we will write a repository interface which extends from JpaRepository. Interestingly, we have not added any methods to this interface nor are we going to provide any implementation class for this. This is because Spring Boot Data JPA autoimplements this interface.

Java
 




xxxxxxxxxx
1


 
1
package com.amitph.spring.tutorials.students.entity;
2
import org.springframework.data.jpa.repository.JpaRepository;
3
import org.springframework.stereotype.Repository;
4
@Repository
5
public interface StudentRepository extends JpaRepository<Student, Long> {
6
}


Write a Rest Controller

Next, we will write a Rest Controller for students and provide all the CRUD methods.

Java
 




xxxxxxxxxx
1


 
1
package com.amitph.spring.tutorials.students;
2
import com.amitph.spring.tutorials.students.entity.StudentRepository;
3
import lombok.RequiredArgsConstructor;
4
import org.springframework.web.bind.annotation.RestController;
5
@RestController
6
@RequiredArgsConstructor
7
public class StudentsController {
8
    private final StudentRepository studentRepository;
9
}


Write a POST Method

A POST method is used to create a new resource. Thus, we are using it to create new students, one at time.

Java
 




x


 
1
@PostMapping("/students")
2
public void postStudent(@RequestBody StudentDto studentDto) {
3
    Student student = new Student();
4
    student.setFirstName(studentDto.getFirstName());
5
    student.setLastName(studentDto.getLastName());
6
    student.setYear(studentDto.getYear());
7
    studentRepository.save(student);
8
}


Users will send a POST request with the student details. The Spring Boot @RequestBody annotation maps the request body parameters into the StudentDto object. Next, we create a new instance of an entity bean and set all the fields. However, we do not set the id field, because it is auto-generated by Hibernate. Finally, we ask the repository to save the newly created entity bean.

Write a PUT Method

The user sends a PUT request to modify an existing resource. Hence, our API endpoint needs a student Id in the request path.

Java
 




x


 
1
@PutMapping("/students/{id}")
2
public void putStudent(@PathVariable long id, @RequestBody StudentDto studentDto) {
3
    Student student = new Student();
4
    student.setStudent_id(id);
5
    student.setFirstName(studentDto.getFirstName());
6
    student.setLastName(studentDto.getLastName());
7
    student.setYear(studentDto.getYear());
8
    studentRepository.save(student);
9
}


We are mapping the request body into a StudentDto object. Using that, we are creating a new Student entity with the provided Id. Because we're using the same Id, Hibernate will not create a new record into the table. Instead, it will update the existing one.

Write a DELETE Method

Writing a DELETE is very straightforward. We expect a student Id to be present in the path variable. Thus, we can ask the repository to delete the particular resource using its Id.

Java
 




x


 
1
@DeleteMapping("/students/{id}")
2
public void deleteStudent(@PathVariable long id) {
3
    studentRepository.deleteById(id);
4
}


Write a GET Method

Next is an example of a GET method where a user can pass a student Id as a path variable to get the Student. The endpoint throws StudentNotFoundException if a student with particular Id is not found.

Java
 




x


 
1
@GetMapping("/students/{id}")
2
public Student getStudent(@PathVariable long id) {
3
    return studentRepository
4
          .findById(id)
5
          .orElseThrow(StudentNotFoundException::new);
6
}


A user may want to get a complete list of students instead. To do that, we will create another GET endpoint, which is generic and returns a List of Student object.

Java
 




x


 
1
@GetMapping("/students")
2
public List<Student> getStudents() {
3
    return studentRepository.findAll();
4
}


Handling a Not Found Exception

In the above endpoints, we throw a StudentNotFoundException. This class is an extension of RuntimeException, which returns HttpStatus.NOT_FOUND (404) in response.

Java
 




x


 
1
package com.amitph.spring.tutorials.students;
2

          
3
import org.springframework.web.bind.annotation.ResponseStatus;
4

          
5
import static org.springframework.http.HttpStatus.NOT_FOUND;
6

          
7
@ResponseStatus(NOT_FOUND)
8
public class StudentNotFoundException extends RuntimeException {
9
    public StudentNotFoundException() {
10
        super();
11
    }
12
}


If you are unfamiliar with ResponseStatus, please read Spring Rest Service Exception Handling.

Run and Test

Let’s run the application and test all the endpoints. To do that, we are using curl, however, you can also use Postman or any similar tool.

Create a New Student

Shell
 




xxxxxxxxxx
1


 
1
~ curl --location --request POST 'localhost:8080/students' \
2
--header 'Content-Type: application/json' \
3
--data-raw '{
4
    "firstName" : "Strong",
5
    "lastName" : "Belwas",
6
    "year" :2025
7
}'


Modify the Student

In the next example, we are changing the first name of the student, whose Id is 2.

Shell
 




xxxxxxxxxx
1


 
1
~ curl --location --request PUT 'localhost:8080/students/2' \
2
--header 'Content-Type: application/json' \
3
--data-raw '{
4
    "firstName" : "JORY",
5
    "lastName" : "CASSEL",
6
    "year" : 2020
7
}'


Retrieve Students

We will call a GET on students by passing the Id 2. The output on the very next line shows the respective Student is correctly returned.

Shell
 




xxxxxxxxxx
1


 
1
~ curl --location --request GET 'localhost:8080/students/2'
2

          
3
{"student_id":2,"firstName":"JORY","lastName":"CASSEL","year":2020}%


We can also GET all students by omitting the path variable of Id.

Shell
 




xxxxxxxxxx
1


 
1
~ curl --location --request GET 'localhost:8080/students/'
2

          
3
[{"student_id":1,"firstName":"Strong","lastName":"Belwas","year":2025},{"student_id":2,"firstName":"JORY","lastName":"CASSEL","year":2020},{"student_id":3,"firstName":"Arthur","lastName":"Dayne","year":2022}]


Delete a Student

To delete a student, we will execute a DELETE request passing the Id as a path variable.

Shell
 




xxxxxxxxxx
1


 
1
~ curl --location --request DELETE 'localhost:8080/students/2'


Summary

In this hand-on tutorial, we learned how to write a Spring Boot CRUD REST API service using Hibernate and JPA. To do so, we wrote the most essential components along with individual HTTP request handlers. Finally, we tested our API by executing POST, PUT, GET, and DELETE endpoints.

Spring Framework Spring Boot Database Web Service REST Web Protocols Hibernate

Published at DZone with permission of Amit Phaltankar. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Spring Boot - How To Use Native SQL Queries | Restful Web Services
  • RESTful Web Services: How To Create a Context Path for Spring Boot Application or Web Service
  • How To Validate HTTP Post Request Body - Restful Web Services With Spring Framework | Spring Boot
  • RESTful Web Services With Spring Boot: Reading HTTP POST Request Body

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!