CRUD operation with Hibernate and Micronaut

Reading Time: 4 minutes

In this blog, we will delve further into Micronaut Framework by using it to create an app using Hibernate and H2 Database. This blog requires prior knowledge of Micronaut Framework and Hibernate. If you’re completely new to Micronaut and would like to learn more about it please go through the Fundamentals of Micronaut.

Micronaut Framework

Introduction

Let’s first briefly know about the technologies that we will be using in this blog:

Micronaut is a JVM-based framework very similar to Spring with some newly added features like AoT(Ahead of Time) compilation and Reflection.

Hibernate is an ORM(Object Relational Mapping) tool that provides us with a framework to map object-oriented domain models to relational databases. 

H2 database is a Java-based relational database that is very lightweight and is generally used as an in-memory database. An in-memory database does not require data to be persisted to a disk.

Application Initialization and Configuration

Just like Spring Initializr here we have the Micronaut Launch page which helps us initialize our code and generate a skeleton project.

Micronaut Launch Page

Once you’re on the launch page, keep all the configurations at default, name your project and then click on the + FEATURES button. Here, type in the dependencies to add to the project. For now, you may skip this and create just an empty project. Following is the complete dependency list from my project. Add the following to your project POM/build.gradle file:

dependencies {
    annotationProcessor("org.projectlombok:lombok")
    annotationProcessor("io.micronaut.data:micronaut-data-processor")
    implementation("io.micronaut:micronaut-validation")
    implementation("io.micronaut:micronaut-runtime")
    implementation("javax.annotation:javax.annotation-api")
    implementation("io.micronaut:micronaut-http-client")
    implementation("io.micronaut.sql:micronaut-jdbc-hikari")
    implementation("io.micronaut.data:micronaut-data-hibernate-jpa")
    runtimeOnly("ch.qos.logback:logback-classic")
    runtimeOnly("com.h2database:h2")
    compileOnly("org.projectlombok:lombok")
}

Once your project is downloaded, open it up on your favorite IDE and make sure the build runs properly. Recheck your build.gradle file if it contains all of the above-mentioned dependencies.

Database Configuration

Next, we would need to configure our H2 Database. Please make sure to add the following configuration to your src/main/resources/application.yml :

datasources:
  default:
    url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    driverClassName: org.h2.Driver
    username: sa
    password: ''
    schema-generate: CREATE_DROP
    dialect: H2

These configurations should be enough. Now run the build in your IDE if not already done, this is just to verify that your project is set up correctly.

Project Structure

I will attach my project at the end of this blog, feel free to refer to the code at any point if you face any issues.

CRUD Implementation

Now let’s design a simple student model to perform the CRUD operations on. First, let’s create a model package and inside it create a model class as shown below:

Path: src/main/java/com/example/knoldus/model/Student.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
@NoArgsConstructor
@Data
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer roll;
    private String firstName;
    private String lastName;
    private Integer standard;
}

Here we are using Lombok annotations to define the constructors and getter/setter methods. This helps us reduce a lot of boilerplate code and complete the code faster.

Next, we will use hibernate to create the repository interface. This will help us connect to the DB and we can perform the CRUD operations using its inbuilt methods. Accordingly, let’s define the interface as follows:

Path: src/main/java/com/example/knoldus/model/StudentRepositoryInterface.java

package com.example.knoldus.model;

import io.micronaut.data.annotation.Repository;
import io.micronaut.data.repository.CrudRepository;

@Repository
public interface StudentRepositoryInterface extends CrudRepository<Student, Integer> {
}

Now, we will further use this interface in our controller, where we will define the endpoints for each of the operations Create, Read, Update, and Delete correspondingly.

So without any further ado, let’s create our controller as follows:

Path: src/main/java/com/example/knoldus/controller/StudentController.java

package com.example.knoldus.controller;

import com.example.knoldus.model.StudentRepositoryInterface;
import com.example.knoldus.model.Student;
import io.micronaut.http.annotation.*;
import lombok.RequiredArgsConstructor;

import java.util.Optional;

@Controller(value="/student")
@RequiredArgsConstructor
public class StudentController {
private final StudentRepositoryInterface student;

@Get("/read")
public Iterable<Student> read(){
return student.findAll();
}

@Delete("/delete/{id}")
public Student delete(@PathVariable Integer id){
Optional<Student> byId = student.findById(id);
if (byId.isEmpty())
throw new IllegalArgumentException("Does not exist: " + id);
student.delete(byId.get());
return byId.get();
}

@Post("/create")
public Student createWithBody(@Body Student student){
return this.student.save(student);
}

@Post("/update")
public Student updateWithBody(@Body Student student){
Optional<Student> studentByRoll = this.student.findById(student.getRoll());
Student entity = studentByRoll.get();
entity.setLastName(student.getLastName());
entity.setStandard(student.getStandard());
entity.setFirstName(student.getFirstName());
return this.student.update(entity);
}

}

Now, here we used the inbuilt methods from CrudRepository to implement the CRUD operations as follows:

Create – save(). We used this method to create the student model in our DB.
Read – findAll(). We used this method to fetch all student models from the DB.

Update – update(). We used this method to update the student model corresponding to its given id(roll no).

Delete – delete(). We used this method to delete a student model corresponding to its given id(roll no).

There are several other variations of these methods. Here’s a fun exercise for you:

Try and implement as many of these methods as you can in your project.

Well, that’s mostly it. We are done with creating the application. Now it is time to run and verify if these endpoints work. You can use Postman to test these endpoints. Alternatively, I have also provided the curl commands to perform each of these functions and test the endpoints.

Please find the complete project at Knoldus Repository.

That would be all for this blog, for more such informative tech blogs on Micronaut and many other technologies please visit Knoldus Blogs.

Written by 

Agnibhas Chattopadhyay is a Software Consultant at Knoldus Inc. He is very passionate about Technology and Basketball. Experienced in languages like C, C++, Java, Python and frameworks like Spring/Springboot, Apache Kafka and CI/CD tools like Jenkins, Docker. He loves sharing knowledge by writing easy to understand tech blogs.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading