Java Spring Jpa Key Value Settings Table Example

Building Complete Spring Boot + Spring Data JPA + PostgreSQL Example

Let's develop a complete CRUD RESTFul APIs for aSimple Employee Management System using Spring Boot 2, Spring Data JPA, and PostgreSQL database.

-> Table of Content

  1. What we'll build?
  2. Tools and Technologies Used
  3. Creating and Importing a Project
  4. Packaging Structure
  5. The pom.xml File
  6. Configuring PostgreSQL
  7. Create JPA Entity - Employee.java
  8. Create Spring Data Repository - EmployeeRepository.java
  9. Create Spring Rest Controller - EmployeeController.java
  10. Exception(Error) Handling for RESTful Services
  11. Running Application
  12. Integration Testing for REST APIs
  13. Testing REST APIs via Postman Client
  14. Source code on GitHub Repository

1. What we'll build

We will buildCRUD RESTFul APIsfor a SimpleEmployee Management System using Spring Boot 2 JPA and PostgreSQL database. Following are five REST APIs (Controller handler methods) created forEmployeeresource.

2. Tools and Technologies Used

  • Spring Boot - 2.0.4.RELEASE
  • JDK- 1.8 or later
  • Spring Framework - 5.0.8 RELEASE
  • Hibernate- 5.2.17.Final
  • JPA
  • Maven- 3.2+
  • IDE- Eclipse or Spring Tool Suite (STS)
  • PostgreSQL - 42.2.5

3. Creating and Importing a Project

There are many ways to create a Spring Boot application. The simplest way is to use Spring Initializr, which is an online Spring Boot application generator.

Look at the above diagram, we have specified the following details:

  • Generate: Maven Project
  • Java Version: 1.8 (Default)
  • Spring Boot:2.0.4
  • Group: net.guides.springboot2
  • Artifact: springboot2-postgresql-jpa-hibernate-crud-example
  • Name : springboot2-postgresql-jpa-hibernate-crud-example
  • Description: springboot2-postgresql-jpa-hibernate-crud-example
  • Package Name : net.guides.springboot2.crud
  • Packaging: jar (This is the default value)
  • Dependencies: Web, JPA,PostgreSQL

Once, all the details are entered, click on Generate Project button will generate a spring boot project and downloads it. Next, Unzip the downloaded zip file and import it into your favorite IDE.

4. Packaging Structure

Following is the packing structure of ourEmployee Management System -

5. The pom.xml File

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"            >     <modelVersion>4.0.0</modelVersion>     <groupId>net.guides.springboot2</groupId>     <artifactId>springboot2-postgresql-jpa-hibernate-crud-example</artifactId>     <version>0.0.1-SNAPSHOT</version>     <packaging>jar</packaging>     <name>springboot2-postgresql-jpa-hibernate-crud-example</name>     <description>springboot2-postgresql-jpa-hibernate-crud-example</description>     <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>2.0.5.RELEASE</version>         <relativePath            />                          <!--              lookup parent from reposictory              -->                        </parent>     <properties>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>         <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-web</artifactId>         </dependency>         <dependency>             <groupId>org.postgresql</groupId>             <artifactId>postgresql</artifactId>             <scope>runtime</scope>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-test</artifactId>             <scope>test</scope>         </dependency>     </dependencies>     <build>         <plugins>             <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>             </plugin>         </plugins>     </build> </project>

6. Configuring PostgreSQL

Let's configure Spring Boot to use PostgreSQL as our data source. You can do that simply by adding PostgreSQL database URL, username, and password in thesrc/main/resources/application.properties file -

              spring.datasource.url=jdbc:postgresql://localhost:5432/employees              spring.datasource.username=postgres              spring.datasource.password=root              spring.jpa.show-sql=true                              ## Hibernate Properties                              #                The SQL dialect makes Hibernate generate better SQL for the chosen database              spring.jpa.properties.hibernate.dialect              = org.hibernate.dialect.PostgreSQLDialect                              #                Hibernate ddl auto (create, create-drop, validate, update)              spring.jpa.hibernate.ddl-auto              = update

7. Create JPA Entity - Employee.java

              package              net.guides.springboot2.crud.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              =                              "employees"              )              public              class              Employee              {              private              long              id;              private              String              firstName;              private              String              lastName;              private              String              emailId;              public              Employee() {        }              public              Employee(String              firstName,              String              lastName,              String              emailId) {              this              .firstName              =              firstName;              this              .lastName              =              lastName;              this              .emailId              =              emailId;     }              @Id              @GeneratedValue(strategy              =              GenerationType                              .IDENTITY)              public              long              getId() {              return              id;     }              public              void              setId(long              id) {              this              .id              =              id;     }              @Column(name              =                              "first_name"              ,              nullable              =              false)              public              String              getFirstName() {              return              firstName;     }              public              void              setFirstName(String              firstName) {              this              .firstName              =              firstName;     }              @Column(name              =                              "last_name"              ,              nullable              =              false)              public              String              getLastName() {              return              lastName;     }              public              void              setLastName(String              lastName) {              this              .lastName              =              lastName;     }              @Column(name              =                              "email_address"              ,              nullable              =              false)              public              String              getEmailId() {              return              emailId;     }              public              void              setEmailId(String              emailId) {              this              .emailId              =              emailId;     }              @Override              public              String              toString() {              return                              "Employee [id="                            +              id              +                              ", firstName="                            +              firstName              +                              ", lastName="                            +              lastName              +                              ", emailId="                            +              emailId              +                              "]"              ;     }   }

8. Create Spring Data Repository - EmployeeRepository.java

              package              net.guides.springboot2.crud.repository;              import              org.springframework.data.jpa.repository.JpaRepository;              import              org.springframework.stereotype.Repository;              import              net.guides.springboot2.springboot2jpacrudexample.model.Employee;              @Repository              public              interface              EmployeeRepository              extends              JpaRepository<Employee,                Long>{  }

9. Create Spring Rest Controller - EmployeeController.java

              package              net.guides.springboot2.crud.controller;              import              java.util.HashMap;              import              java.util.List;              import              java.util.Map;              import              javax.validation.Valid;              import              org.springframework.beans.factory.annotation.Autowired;              import              org.springframework.http.ResponseEntity;              import              org.springframework.web.bind.annotation.DeleteMapping;              import              org.springframework.web.bind.annotation.GetMapping;              import              org.springframework.web.bind.annotation.PathVariable;              import              org.springframework.web.bind.annotation.PostMapping;              import              org.springframework.web.bind.annotation.PutMapping;              import              org.springframework.web.bind.annotation.RequestBody;              import              org.springframework.web.bind.annotation.RequestMapping;              import              org.springframework.web.bind.annotation.RestController;              import              net.guides.springboot2.springboot2jpacrudexample.exception.ResourceNotFoundException;              import              net.guides.springboot2.springboot2jpacrudexample.model.Employee;              import              net.guides.springboot2.springboot2jpacrudexample.repository.EmployeeRepository;              @RestController              @RequestMapping(                "/api/v1"              )              public              class              EmployeeController              {              @Autowired              private              EmployeeRepository              employeeRepository;              @GetMapping(                "/employees"              )              public              List<Employee>              getAllEmployees() {              return              employeeRepository.findAll();     }              @GetMapping(                "/employees/{id}"              )              public              ResponseEntity<Employee>              getEmployeeById(@PathVariable(value              =                              "id"              )              Long              employeeId)              throws              ResourceNotFoundException              {              Employee              employee              =              employeeRepository.findById(employeeId)           .orElseThrow(()              -              >              new              ResourceNotFoundException(                "Employee not found for this id ::                "                            +              employeeId));              return              ResponseEntity              .ok().body(employee);     }              @PostMapping(                "/employees"              )              public              Employee              createEmployee(@Valid              @RequestBody              Employee              employee) {              return              employeeRepository.save(employee);     }              @PutMapping(                "/employees/{id}"              )              public              ResponseEntity<Employee>              updateEmployee(@PathVariable(value              =                              "id"              )              Long              employeeId,              @Valid              @RequestBody              Employee              employeeDetails)              throws              ResourceNotFoundException              {              Employee              employee              =              employeeRepository.findById(employeeId)         .orElseThrow(()              -              >              new              ResourceNotFoundException(                "Employee not found for this id ::                "                            +              employeeId));          employee.setEmailId(employeeDetails.getEmailId());         employee.setLastName(employeeDetails.getLastName());         employee.setFirstName(employeeDetails.getFirstName());              final              Employee              updatedEmployee              =              employeeRepository.save(employee);              return              ResponseEntity              .ok(updatedEmployee);     }              @DeleteMapping(                "/employees/{id}"              )              public              Map<String,                Boolean>              deleteEmployee(@PathVariable(value              =                              "id"              )              Long              employeeId)              throws              ResourceNotFoundException              {              Employee              employee              =              employeeRepository.findById(employeeId)        .orElseThrow(()              -              >              new              ResourceNotFoundException(                "Employee not found for this id ::                "                            +              employeeId));          employeeRepository.delete(employee);              Map<String,                Boolean>              response              =              new              HashMap<>();         response.put(                "deleted"              ,              Boolean                              .TRUE);              return              response;     } }

10. Exception(Error) Handling for RESTful Services

Spring Boot provides a good default implementation for exception handling for RESTful Services. Let's quickly look at the default Exception Handling features provided by Spring Boot.

Resource Not Present

{                              "timestamp"              :              1512713804164,                              "status"              :              404,                              "error"              :                              "Not Found"              ,                              "message"              :                              "No message available"              ,                              "path"              :                              "/some-dummy-url"                            }

That's a cool error response. It contains all the details that are typically needed.

What happens when we throw an Exception?

Let's see what Spring Boot does when an exception is thrown from a Resource. we can specify the Response Status for a specific exception along with the definition of the Exception of the'@ResponseStatus' annotation.

Let's create aResourceNotFoundException.java class.

              package              net.guides.springboot2.crud.exception              ;              import              org.springframework.http.HttpStatus;              import              org.springframework.web.bind.annotation.ResponseStatus;              @ResponseStatus(value              =              HttpStatus                              .NOT_FOUND)              public              class              ResourceNotFoundException              extends              Exception{              private              static              final              long              serialVersionUID              =              1L;              public              ResourceNotFoundException(String              message){              super(message);     } }

Customizing Error Response Structure

The default error response provided by Spring Boot contains all the details that are typically needed.

However, you might want to create a framework independent response structure for your organization. In that case, you can define a specific error response structure.

Let's define a simple error response bean.

              package              net.guides.springboot2.crud.exception              ;              import              java.util.Date;              public              class              ErrorDetails              {              private              Date              timestamp;              private              String              message;              private              String              details;              public              ErrorDetails(Date              timestamp,              String              message,              String              details) {              super();              this              .timestamp              =              timestamp;              this              .message              =              message;              this              .details              =              details;     }              public              Date              getTimestamp() {              return              timestamp;     }              public              String              getMessage() {              return              message;     }              public              String              getDetails() {              return              details;     } }

To useErrorDetails to return the error response, let's create aGlobalExceptionHandler class annotated with@ControllerAdvice annotation. This class handles exception specific and global exception in a single place.

              package              net.guides.springboot2.crud.exception              ;              import              java.util.Date;              import              org.springframework.http.HttpStatus;              import              org.springframework.http.ResponseEntity;              import              org.springframework.web.bind.annotation.ControllerAdvice;              import              org.springframework.web.bind.annotation.ExceptionHandler;              import              org.springframework.web.context.request.WebRequest;              @ControllerAdvice              public              class              GlobalExceptionHandler              {              @ExceptionHandler(ResourceNotFoundException              .class)              public              ResponseEntity<?>              resourceNotFoundException(ResourceNotFoundException              ex,              WebRequest              request) {              ErrorDetails              errorDetails              =              new              ErrorDetails(new              Date(), ex.getMessage(), request.getDescription(false));              return              new              ResponseEntity<>(errorDetails,              HttpStatus                              .NOT_FOUND);     }              @ExceptionHandler(Exception              .class)              public              ResponseEntity<?>              globleExcpetionHandler(Exception              ex,              WebRequest              request) {              ErrorDetails              errorDetails              =              new              ErrorDetails(new              Date(), ex.getMessage(), request.getDescription(false));              return              new              ResponseEntity<>(errorDetails,              HttpStatus                              .INTERNAL_SERVER_ERROR);     } }

11. Running Application

This spring boot application has an entry point Java class calledSpringBootCrudRestApplication.java with thepublic static void main(String[] args) method, which you can run to start the application.

              import              org.springframework.boot.SpringApplication;              import              org.springframework.boot.autoconfigure.SpringBootApplication;              @SpringBootApplication              public              class              Application              {              public              static              void              main(String[]              args) {              SpringApplication              .run(Application              .class, args);     } }
  • @Configuration tags the class as a source of bean definitions for the application context.

  • @EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.

  • Normally you would add@EnableWebMvc for a Spring MVC app, but Spring Boot adds it automatically when it seesspring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.

  • @ComponentScan tells Spring to look for other components, configurations, and services in the hello package, allowing it to find the controllers.

Themain() method uses Spring Boot'sSpringApplication.run()method to launch an application.

The PostgreSQL database looks like:

12. Integration Testing for REST APIs

There is a separate beautiful article for integration testing for REST APIs on:

>> Spring Boot 2 REST APIs Integration Testing

13. Testing REST APIs via Postman Client

1. Create Employee REST API

HTTP Method: POST

Note that request and response JSON in the above diagram, the response contains database auto generated id.

2. Get Employee by ID REST API

HTTP Method: GET

3. Get all Employees REST API

HTTP Method: GET

4. Update Employee REST API

HTTP Method: GET

5. Delete Employee REST API

HTTP Method:DELETE

14. Source code on GitHub

talaveraformselly.blogspot.com

Source: https://www.javaguides.net/2019/08/spring-boot-spring-data-jpa-postgresql-example.html

0 Response to "Java Spring Jpa Key Value Settings Table Example"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel