Spring boot crud operations example with hibernate


Spring boot crud operations

1. Overview

In this example, we will be working on crud operations and exploring them through with Spring REST APIs so that any front-end clients can consume these operations. The demo operations enable the clients to modify the Supplier records in database.

Here we are trying to explain this in very short so, it can be understood easily, and we are not covering any business logic or complex logic here.

2. Maven Dependencies

In below example, we will be using maven project to add runtime jars in project POM. If you are using any other project type example gradle then please use following dependencies.

You can also download projects from  Spring Initializer URL:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath />
        <!-- lookup parent from repository -->
    </parent>
    <groupId>com.onlinetutorials.tech</groupId>
    <artifactId>SpringBoot2Demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringBoot2Demo</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-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</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>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Let’s Explore some dependencies here:

spring-boot-starter-web :

This is being used for building web layer of spring boot application, this will also include REST APIs, Spring MVC and this will internally use Tomcat as internal server with default port 8080.
spring-boot-starter-data-jpa : This is being used for building spring data, HikariCP, Hibernate, JPA API, JPA Implementation (Hibernate is always considered as default).

h2 :

It is an In memory database provided by spring boot POC purpose.

spring-boot-starter-test :

It is being used for test any Spring Boot applications this will internally load libraries for JUnit and Mockito.

3. Hibernate Configuration

3.1. Entity and repository

It is always recommended creating entity model whenever you are dealing with Spring boot data, this class will help to create repository layer.

It is always good practice to extend JpaRepository interface to allow creating repository implementations automatically. Below is the generic implementation of parameters on JpaRepository.

Always think of to include only JPA API annotations of (javax.persistence.*) to decouple hibernate.

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "onlineTutorials")
public class SupplierEntity {

 @Id
 @GeneratedValue
 private Long id;

 @Column(name = "first_name")
 private String firstName;

 @Column(name = "last_name")
 private String lastName;

 @Column(name = "email", nullable = false, length = 200)
 private String email;

 //Generate Setters and getters or

 Use Lombok

 @Override
 public String toString() {
  return "SupplierEntity [id=" + id + ", firstName=" + firstName +
   ", lastName=" + lastName + ", email=" + email + "]";
 }
}

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.onlinetutorials.tech.entity.SupplierEntity;

@Repository
public interface SupplierRepository
extends JpaRepository < SupplierEntity, Long > {

}

3.2. Data source Configuration

Now if we want to connect database, we should configure the data source.
As here We are using H2 database so with all the properties with respect to H2 database are explained below:

spring.datasource.url=jdbc:h2:file:~/test 
spring.datasource.driverClassName=org.h2.Driver 
spring.datasource.username=sa 
spring.datasource.password= 
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 
# Enabling H2 Console 
spring.h2.console.enabled=true 
# Custom H2 Console URL 
spring.h2.console.path=/h2-console 
# create database schema from SQL files 
spring.jpa.hibernate.ddl-auto=none 
#Turn Statistics on and log SQL stmts 
spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true 
spring.jpa.properties.hibernate.generate_statistics=false 
#logging.level.org.hibernate.type=trace 
#logging.level.org.hibernate.stat=debug logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n

4. Service (uses repository)

This is one of the optional layer in spring boot architecture but it is always recommended here to implementing your business logic here and from here just connect your respective repository for performing crud operations.

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.onlinetutorials.tech.entity.SupplierEntity;
import com.onlinetutorials.tech.exception.RecordNotFoundException;
import com.onlinetutorials.tech.repository.SupplierRepository;
@Service public class SupplierService {
 @Autowired 
 SupplierRepository repository;
 public List < SupplierEntity > getAllSuppliers() {
  List < SupplierEntity > SupplierList = repository.findAll();
  if (SupplierList.size() > 0) {
   return SupplierList;
  } else {
   return new ArrayList < SupplierEntity > ();
  }
 }
 public SupplierEntity getSupplierById(Long id) throws RecordNotFoundException {
  Optional < SupplierEntity > Supplier = repository.findById(id);
  if (Supplier.isPresent()) {
   return Supplier.get();
  } else {
   throw new RecordNotFoundException("No Supplier record exist for given id");
  }
 }
 public SupplierEntity createOrUpdateSupplier(SupplierEntity entity) throws RecordNotFoundException {
  Optional < SupplierEntity > Supplier = repository.findById(entity.getId());
  if (Supplier.isPresent()) {
   SupplierEntity newEntity = Supplier.get();
   newEntity.setEmail(entity.getEmail());
   newEntity.setFirstName(entity.getFirstName());
   newEntity.setLastName(entity.getLastName());
   newEntity = repository.save(newEntity);
   return newEntity;
  } else {
   entity = repository.save(entity);
   return entity;
  }
 }
 public void deleteSupplierById(Long id) throws RecordNotFoundException {
  Optional < SupplierEntity > Supplier = repository.findById(id);
  if (Supplier.isPresent()) {
   repository.deleteById(id);
  } else {
   throw new RecordNotFoundException("No Supplier record exist for given id");
  }
 }
}

5. REST Controller

Here just expose all URLs for operations or applications endpoints.

Front-end will connect with these endpoints to perform respective operation get/update/delete Suppliers records.

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.onlinetutorials.tech.entity.SupplierEntity;
import com.onlinetutorials.tech.exception.RecordNotFoundException;
import com.onlinetutorials.tech.service.SupplierService;
@RestController @RequestMapping("/Suppliers") 
public class SupplierController {
 @Autowired 
 SupplierService service;
 @GetMapping public ResponseEntity < List < SupplierEntity >> getAllSuppliers() {
  List < SupplierEntity > list = service.getAllSuppliers();
  return new ResponseEntity < List < SupplierEntity >> (list, new HttpHeaders(), HttpStatus.OK);
 }
 @GetMapping("/{id}") public ResponseEntity < SupplierEntity > getSupplierById(@PathVariable("id") Long id) throws RecordNotFoundException {
  SupplierEntity entity = service.getSupplierById(id);
  return new ResponseEntity < SupplierEntity > (entity, new HttpHeaders(), HttpStatus.OK);
 }
 @PostMapping public ResponseEntity < SupplierEntity > createOrUpdateSupplier(SupplierEntity Supplier) throws RecordNotFoundException {
  SupplierEntity updated = service.createOrUpdateSupplier(Supplier);
  return new ResponseEntity < SupplierEntity > (updated, new HttpHeaders(), HttpStatus.OK);
 }
 @DeleteMapping("/{id}") public HttpStatus deleteSupplierById(@PathVariable("id") Long id) throws RecordNotFoundException {
  service.deleteSupplierById(id);
  return HttpStatus.FORBIDDEN;
 }
}

Learn more about spring boot annotations @RestController, @RequestMapping, @GetMapping, @PostMapping and @DeleteMapping to map various URIs to controller methods.

  1. Spring boot crud operations demo
    Yuppy we have completed, let’s start the spring boot application.

%d bloggers like this: