This tutorial will show you how to integrate in-memory H2 database with Spring Boot 2.1 and build using Gradle tool. We will see here simple JPA example to understand how it works.

What is an in-memory database?

An in memory database is created when an application starts up and destroyed when the application is stopped.

Using in memory database has lots of advantages such as:

No need to setup the database
Almost zero configuration
Almost zero maintenance
It is very easy to use for learning, proof of concepts and unit testing

H2 is one of the popular in memory database and Spring Boot provides very easy configuration for an in memory database like H2.

Why is in memory database required?

Let’s consider a cenario when you want to do a quick proof of concept(POC) and using a traditional database involves a lot of overhead.

Another scenario, on your unit tests:

  • You don’t want them to fail when some data/schema get changed in the database.
  • Multiple developers might be running the tests in parallel.

Prerequisites

Spring Boot 2.1, H2 1.3.176, Gradle 4.x, Java 1.8, Eclipse 4.9

Project Setup in Eclipse

Create a Gradle project in Eclipse IDE. Modify the build.gradle script to have something like following details:

buildscript {
	ext {
		springBootVersion = '2.1.3.RELEASE'
	}
    repositories {
    	mavenLocal()
    	mavenCentral()
    }
    dependencies {
    	classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
    
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
	mavenLocal()
    mavenCentral()
}

dependencies {
	compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
	compile("org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}")
	runtime("com.h2database:h2:1.3.176")
}

As you see in the above build script we have just included the required dependencies for Spring Data JPA, H2 in memory database and Web module to perform REST operations with H2 database.

Building the blank project

Build the empty project to add the required jar files into project in Eclipse.

Note: you may get issue related to Main class not found in the project. So don’t worry about it and refresh the project in Eclipse from the option. Do right click on the project -> Gradle -> Refresh gradle project.

Once the refresh is done in Eclipse, you write below code.

Creating Entity Class

Create below entity class in order to define employee objects.

package com.jeejava.h2.entity;

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

@Entity
public class Employee {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;
	private String name;
	@Column(name = "email_address")
	private String email;

	public Employee() {
	}

	public Employee(Integer id, String name, String email) {
		this.id = id;
		this.name = name;
		this.email = email;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

}

In the above class we have annotated the Employee class with @Entity to map the Employee object with H2 database table.

We have denoted primary column with @Id and we are also generating the auto-increment values for primary column using @Generated annotation with generation type specification.

If your column name and Java class’s attribute name is same then you don’t need to specify the corresponding table column name @Column annotation. For example, in the above Employee class the corresponding table will have same name with id and name but email as a Java attribute, whereas the corresponding column name in table will be email_address.

We don’t need to put any database configuration into application.properties or application.yml file as we will use the default database configuration for H2 database. The database configuration for H2 is set by Spring Boot given below:

spring.datasource.url=jdbc:h2:mem:testdb  
spring.datasource.driverClassName=org.h2.Driver  
spring.datasource.username=sa  
spring.datasource.password=  
spring.h2.console.enabled=false

Creating Repository Interface

Create repository interface that will extend Spring Data JPA’s JpaRepository interface to get the default functionalities from the Spring API.

package com.jeejava.h2.repository;

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

import com.jeejava.h2.entity.Employee;

public interface EmployeeRepository extends JpaRepository<Employee, Integer> {

	Employee findByName(String name);

	Employee findByEmail(String email);

}

In the above repository interface, we have declared two methods for finding the employee either by name or email.

Creating REST controller class

Create Spring REST controller class to retrieve the data from H2 database – employee table.

package com.jeejava.h2.rest.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.jeejava.h2.entity.Employee;
import com.jeejava.h2.repository.EmployeeRepository;

@RestController
public class EmployeeRestController {

	@Autowired
	private EmployeeRepository employeeRepository;

	@GetMapping("/employee/name/{name}")
	public ResponseEntity<Employee> getEmployeeByName(@PathVariable String name) {
		Employee employee = employeeRepository.findByName(name);
		return new ResponseEntity<Employee>(employee, HttpStatus.OK);
	}

	@GetMapping("/employee/email/{email}")
	public ResponseEntity<Employee> getEmployeeByEmail(@PathVariable String email) {
		Employee employee = employeeRepository.findByEmail(email);
		return new ResponseEntity<Employee>(employee, HttpStatus.OK);
	}

}

In the above class we have defined two methods to find the employee when name or email is passed to the path parameter of the URI.

Creating the application.yml

Create application.yml file under classpath resource directory – src/main/resources.

spring:
   jpa:
      show-sql: true
   h2:
      console:
         enabled: true
         
server:
   port: 9000

We want to start the Tomcat server on port 9000 instead of default port 8080.

We have also configured h2 console enabled and we want to see the query in the console when gets executed.

Creating data.sql

The data.sql file is required in order to insert some initial data to show end users when they call the REST service to fetch the employee data in order to heads up.

insert into employee(name,email_address)
values('Soumitra','soumitra@email.com');
insert into employee(name,email_address)
values('Liton','liton@email.com');
insert into employee(name,email_address)
values('Suman','suman@email.com');
insert into employee(name,email_address)
values('Debabrata','debabrata@email.com');

The above file gets executed during Spring Boot application gets start up.

Creating the main class

Create the main class in order to start up and deploy the Spring Boot application into embedded Tomcat server.

package com.jeejava.h2.main;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EntityScan("com.jeejava.h2.entity")
@EnableJpaRepositories("com.jeejava.h2.repository")
@SpringBootApplication(scanBasePackages = "com.jeejava.h2")
public class EmployeeApplication {

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

}

In the above class we have let the Spring Boot application know where to look for Entity class and Repository interface.

Testing the application

Run the main class as a Java application.

Your application will be started and deployed into Tomcat server. You will find some important messages in the console, such as:

...
Finished Spring Data repository scanning in 113ms. Found 1 repository interfaces.
...
Hibernate: drop table employee if exists
Hibernate: create table employee (id integer generated by default as identity, email_address varchar(255), name varchar(255), primary key (id))
...
Tomcat started on port(s): 9000 (http) with context path ''
...

When you hit the URL – http://localhost:9000/employee/name/Soumitra, the corresponding response is:

{"id":1,"name":"Soumitra","email":"soumitra@email.com"}

The corresponding output in the console will be something similar to the below:

Hibernate: select employee0_.id as id1_0_, employee0_.email_address as email_ad2_0_, employee0_.name as name3_0_ from employee employee0_ where employee0_.name=?

When you hit the URL – http://localhost:9000/employee/email/liton@email.com, the corresponding response we get as:

{"id":2,"name":"Liton","email":"liton@email.com"}

The corresponding output in the console will be something similar to the below:

Hibernate: select employee0_.id as id1_0_, employee0_.email_address as email_ad2_0_, employee0_.name as name3_0_ from employee employee0_ where employee0_.email_address=?

Thanks for reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit

Leave a Reply

Your email address will not be published. Required fields are marked *