Build REST CRUD APIs with Micronaut and Data Hibernate JPA

Hello everyone, today we will learn how to build RESTful CRUD APIs using Micronaut and Data Hibernate JPA with the help of one simple example.

Related topics,

Micronaut is a modern, JVM-predicated, full-stack Java framework designed for building modular, facilely testable JVM applications with support for Java, Kotlin and the Groovy language.

Micronaut  provides:

  • Dependency Injection and Inversion of Control (IoC)
  • Aspect-Oriented Programming (AOP)
  • Sensible Defaults and Auto-ConfigurationMessage-Driven Applications
  • HTTP Routing
  • Client-Side Load Balancing
  • Command-Line Applications
  • HTTP ServersDistributed Configuration
  • Service Discovery
  • Fast startup time
  • Reduced memory footprint
  • Minimal use of reflection
  • Minimal use of proxies
  • No runtime bytecode generation
  • Easy Unit Testing

Technologies used:

  • Java 11
  • Micronaut 3.1.1
  • Micronaut Data Hibernate JPA 3.1.1
  • H2DB
  • Micronaut-Hikari-Cp 3.1.1
  • Maven 3.6.3

Final Project Structure:


Dependency management - Maven - Pom.xml

<?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>org.knf.dev.demo</groupId>
<artifactId>micronaut-data-jpa-crud</artifactId>
<version>0.1</version>
<packaging>${packaging}</packaging>

<parent>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-parent</artifactId>
<version>3.1.1</version>
</parent>

<properties>
<packaging>jar</packaging>
<jdk.version>11</jdk.version>
<release.version>11</release.version>
<micronaut.version>3.1.1</micronaut.version>
<exec.mainClass>org.knf.dev.demo.Application</exec.mainClass>
<micronaut.runtime>netty</micronaut.runtime>
</properties>

<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-validation</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micronaut.test</groupId>
<artifactId>micronaut-test-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-http-client</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-http-server-netty</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-runtime</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micronaut.data</groupId>
<artifactId>micronaut-data-hibernate-jpa</artifactId>
</dependency>
<dependency>
<groupId>io.micronaut.sql</groupId>
<artifactId>micronaut-jdbc-hikari</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>io.micronaut.build</groupId>
<artifactId>micronaut-maven-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- Uncomment to enable incremental compilation -->
-- <useIncrementalCompilation>false</useIncrementalCompilation> -->

<annotationProcessorPaths
combine.children="append">
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-http-validation</artifactId>
<version>${micronaut.version}</version>
</path>
<path>
<groupId>io.micronaut.data</groupId>
<artifactId>micronaut-data-processor</artifactId>
<version>${micronaut.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Amicronaut.processing.group=org.knf.dev.demo</arg>
<arg>-Amicronaut.processing.module=micronaut-data-jpa-crud</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>

</project>

Data source & JPA configuration in src/main/resources/application.yml

micronaut:
application:
name: micronautDataJPA
datasources:
default:
url: jdbc:h2:mem:devDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
driverClassName: org.h2.Driver
username: sa
password: ''
jpa.default.properties.hibernate.hbm2ddl.auto: update

jpa:
default:
properties:
hibernate:
hbm2ddl:
auto: update
show_sql: true

Entity class

package org.knf.dev.demo.entity;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "users")
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
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;
}
public User(Long id, String firstName, String lastName, String emailId) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.emailId = emailId;
}

public User() {
super();
}

}

UserRepository

package org.knf.dev.demo.repository;

import org.knf.dev.demo.entity.User;

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


@Repository
public interface UserRepository extends CrudRepository<User,Long>{

}

UserController

package org.knf.dev.demo.controller;

import java.util.List;
import java.util.Optional;
import org.knf.dev.demo.entity.User;
import org.knf.dev.demo.repository.UserRepository;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Delete;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.annotation.Put;
import io.micronaut.scheduling.TaskExecutors;
import io.micronaut.scheduling.annotation.ExecuteOn;

@ExecuteOn(TaskExecutors.IO)
@Controller("/users")
public class UserController {

protected final UserRepository userRepository;

public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Get
public List<User> getUsers() {
return (List<User>) userRepository.findAll();
}

@Get("/{id}")
public Optional<User> getUser(Long id) {
return userRepository.findById(id);
}

@Put("/{id}")
public User updateUser(Long id, @Body User user) throws Exception {
if (userRepository.existsById(id)) {
user.setId(id);
userRepository.update(user);
return user;
} else {
/*
* For demo purposes, I am using Generic Exception.
* In a real scenario, you must
* implement custom exception handling.
*/ throw new Exception("Id Not Found");
}
}

@Post
public User addUser(@Body User user) {
return userRepository.save(user);
}

@Delete("/{id}")
public void deleteUser(Long id) throws Exception {
if (userRepository.existsById(id)) {
userRepository.deleteById(id);
} else {
/*
* For demo purposes, I am using Generic Exception.
* In a real scenario, you must
* implement custom exception handling.
*/
throw new Exception("Id Not Found");
}
}

}

Main Class

package org.knf.dev.demo;

import io.micronaut.runtime.Micronaut;

public class Application {

public static void main(String[] args) {
Micronaut.run(Application.class, args);
}
}

Verify REST APIs

Run as Java Application 
       or
mvn mn:run

Add User:



Get All User:



Get User By Id:



Delete User:



Update User:



Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete