Spring Boot + Jersey + JPA + Hibernate REST CRUD APIs Example
Hello everyone, today we will learn how to develop CRUD REST APIs using the integration of Jersey with Spring boot, JPA/Hibernate, and H2DB as a database.
Jersey framework for developing RESTful Web Services in Java. It provides support for JAX-RS APIs and serves as a JAX-RS Reference Implementation.
What we’ll build?
We are developing CRUD REST APIs using the integration of Jersey with Spring boot, JPA/Hibernate, and H2DB as a database.
- /api/v1/employees - GET
- /api/v1/employees - POST
- /api/v1/employees/{id} - PUT
- /api/v1/employees/{id} - DELETE
- /api/v1/employees/{id} - GET
Application Directory structure
Maven[pom.xml]
A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details utilized by Maven to build the project. It contains default values for most projects. Some of the configurations that can be designated in the POM is the project dependencies, the plugins or goals that can be executed, the build profiles, and so on. Other information such as the project version, description, developers, mailing lists, and such can withal be designated.
<?xml version="1.0" encoding="UTF-8"?>
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.demo</groupId>
<artifactId>springboot_jersey_rdbms_restful_api_crud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot_jersey_rdbms_restful_api_crud</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.datasource.url=jdbc:h2:mem:knfdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.h2.console.enabled=true
Modal class[Employee.java]
package com.knf.demo.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
@Column(name = "email_address", nullable = false)
private String emailId;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
}
Repository[EmployeeRepository.java]
package com.knf.demo.repository;
import org.springframework.data.repository.CrudRepository;
import com.knf.demo.model.Employee;
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
}
Controller[EmployeeController.java]
package com.knf.demo.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import com.knf.demo.model.Employee;
import com.knf.demo.repository.EmployeeRepository;
@Component
@Path("/api/v1")
public class EmployeeController {
@Autowired
private EmployeeRepository employeeRepository;
@GET
@Produces("application/json")
@Path("/employees")
public List<Employee> getAllEmployees() {
return (List<Employee>) employeeRepository.findAll();
}
@GET
@Produces("application/json")
@Consumes("application/json")
@Path("/employees/{id}")
public ResponseEntity<Employee> getEmployeeById(@PathParam(value = "id")
Long employeeId) {
Employee employee = employeeRepository.findById(employeeId).
orElseThrow();
return ResponseEntity.ok().body(employee);
}
@POST
@Produces("application/json")
@Consumes("application/json")
@Path("/employees")
@PostMapping("/employees")
public Employee createEmployee(Employee employee) {
return employeeRepository.save(employee);
}
@PUT
@Produces("application/json")
@Consumes("application/json")
@Path("/employees/{id}")
public ResponseEntity<Employee> updateEmployee(@PathParam(value = "id")
Long employeeId,
@RequestBody Employee employeeDetails) {
Employee employee = employeeRepository.findById(employeeId).
orElseThrow();
employee.setEmailId(employeeDetails.getEmailId());
employee.setLastName(employeeDetails.getLastName());
employee.setFirstName(employeeDetails.getFirstName());
return ResponseEntity.ok(employeeRepository.save(employee));
}
@DELETE
@Produces("application/json")
@Consumes("application/json")
@Path("/employees/{id}")
public Map<String, Boolean> deleteEmployee(@PathParam(value = "id")
Long employeeId) {
Employee employee = employeeRepository.findById(employeeId).
orElseThrow();
employeeRepository.delete(employee);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", Boolean.TRUE);
return response;
}
}
App Configuration[JerseyConfiguration.java]
package com.knf.demo.config;
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
import com.knf.demo.controller.EmployeeController;
@Component
@ApplicationPath("/boot-jersey-knf")
public class JerseyConfiguration extends ResourceConfig {
public JerseyConfiguration() {
register(EmployeeController.class);
}
}
Main Driver Class[SpringbootJerseyRdbmsRestfulApiCrudApplication.java]
package com.knf.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootJerseyRdbmsRestfulApiCrudApplication {
public static void main(String[] args) {
SpringApplication.run(
SpringbootJerseyRdbmsRestfulApiCrudApplication.class, args);
}
}
Run & Test
Run Spring Boot application with the command: mvn spring-boot:run
Fetch All Employee
Fetch Employee By ID
Update Employee
Delete Employee By ID