Spring Boot With H2 Database

In this article, we will see how to use Spring Boot with H2 Database.Just like other databases, there’s full intrinsic support for it in the Spring Boot ecosystem.

Spring Boot with H2 Database

H2 database is a relatively new and an open-source, in-memory relational database management system that is written in Java. Just like other in-memory databases, H2 database relies on system memory for loading and persisting the data, instead of physical disk storage. It is an embedded database which we can use in our java application or run in a client-server mode.In-memory databases are very fast as the data access is done from System memory, rather than disk storage. They are volatile, i.e., in case of application restart, all the data is lost.

We can use in-memory databases like H2 for POCs and during the development phase when iterating through schema changes without making changes to actual persistent databases like MYSQL. Another use case where H2 is used is during the unit testing of our applications. H2 database can’t be used for production application.

1. H2 Database Configuration With Spring Boot

To use Spring Boot with H2 Database, we need to configure H2 database in our application.Configuration is pretty straight forward if we are using Spring. We first need to add the required dependency for H2 in pom.xml if using maven as build tool. After the required dependency is added to the project, we need to add following properties to application.properties or application.yaml file. In this way, by adding required properties to the properties file, we can connect to any database. Here are some of the properties that are important while we setting up the H2 Database with Sprig Boot.

  • data source URL: To establish a database connection, Java’s Datasource interface uses a URL and some credentials. In the URL, we need to provide the names of in-memory database and schema. Since we are using H2 database, ‘mem’ is the name of the in-memory database and ‘testdb is the name of schema, provided by H2 by default.
  • driver class name: H2 is a java database and we can interact with it by using JDBC. For that first we need to register the JDBC database driver. Here we provide the driver class name.   
  • username: By default, the username provided is ‘sa’. We can override this value by setting the appropriate name in the application.properties file.
  • password: By default, the password provided is empty. We can override this value by setting the appropriate password in the application.properties file.

2. Dependencies

To use Spring Boot with H2 database, we need to add the required H2 dependency.Scope provided is runtime, as we are going to use H2 when running our unit test cases. If we are using maven as build tool, add the below dependency in pom.xml.

<dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <scope>runtime</scope>
</dependency>

Alternatively, we can use gradle script as below:

dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile group: 'junit', name: 'junit', version: '4.+'
    compile group: 'com.h2database', name: 'h2', version: '1.3.148'
}

3. H2 Database Configuration With Spring Boot

To be able to connect our application to a database, we need to add below configuration. By default, spring configures our application to connect to an in-memory database like H2 with default values for user as ‘sa’ and empty password. We can override these values in the application.properties or application.yaml file.

spring.datasource.url=jdbc:h2:mem:javadevjournal 
spring.datasource.driverClassName=org.h2.Driver 
spring.datasource.username=sa 
spring.datasource.password=pass 
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

Alternatively, we can use application.yaml file for the configuration:

spring: 
   datasource: 
      url: jdbc:h2:mem: javadevjournal
      username: sa 
      password: pass 
      driverClassName: org.h2.Driver 
   jpa: 
      spring.jpa.database-platform: org.hibernate.dialect.H2Dialect

H2 database supports two persistence modes. In-memory and file-based storage. Adding the above properties will provide an in-memory H2 implementation, which is volatile, i.e., data will be lost when application restarts.

If we need a file-based storage, then we can update the spring.datasource.url property in the application.properties or application.yaml file.

spring.datasource.url=jdbc:h2:file:/data/filename

We can also use the yaml configuration for this:

spring:
  datasource:
    url:  jdbc:h2:file:/data/filename

4. Handling Database Operations

Let’s take a look at some database operations for our Spring Boot with H2 Database application.Performing the database operations like CRUD with H2 in a Spring boot project is similar as with other SQL databases.

4.1. Initializing the DataSource

To use a database like MYSQL, we first need to install them, then create the schemas, and then create the tables and populate data. When using an in-memory database, we don’t need to separately install a database. The database and the schema live inside the memory of the application we are running. Database schema is created looking at the configuration provided to the application. We can provide SQL scripts to initialize the database which can contain create table and insert to table queries. If we have a spring boot project and JPA dependency, then, by looking at the entities present, entire database will be created at application start up.

To populate the data in tables at application start up, we can add data.sql file in src/main/resources folder. By default, Spring boot will automatically pick this file and run it against our embedded H2 database instance. We can change this default behavior by setting spring.sql.init.mode to never.

INSERT INTO employee (id, name, salary) VALUES (1, 'Amy', 3500.0);
INSERT INTO employee (id, name, salary) VALUES (2, 'Jake', 4000.0);
INSERT INTO employee (id, name, salary) VALUES (3, 'Charles', 3000.0);
INSERT INTO employee (id, name, salary) VALUES (4, 'Terry', 5500.0);
INSERT INTO employee (id, name, salary) VALUES (5, 'Rosa', 5000.0);

4.2. Using Hibernate

The data.sql script executes before hibernate initialization by default.  Since we are recreating the schema generated by Hibernate every time, we need to set one more property.

spring.jpa.defer-datasource-initialization=true

By setting this property, data.sql will be executed after schema generation is done by hibernate. Also, we can use schema.sql to overwrite the schema generated by hibernate prior to data population using data.sql.

5. Building Spring Boot App Using H2 Database

Let’s build an application using Spring Boot with H2 Database.We will create an employee entity and perform CRUD operations on it in a REST application.We are using spring initializr to get the project structure ready.

Spring Boot with H2 Database

Here is how the project structure look like after we import it to the IDE of choice:

Spring Boot with H2 Database

This is how the complete pom.xml look like. Please aware that it can change based on the dependencies used for your project.



<?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 https://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.6.2</version>
      <relativePath />
      <!-- lookup parent from repository -->
   </parent>
   <groupId>com.javadevjournal</groupId>
   <artifactId>spring-boot-h2</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>spring-boot-h2</name>
   <description>Spring Boot project for H2 illustration</description>
   <properties>
      <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>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>
            <configuration>
               <excludes>
                  <exclude>
                     <groupId>org.projectlombok</groupId>
                     <artifactId>lombok</artifactId>
                  </exclude>
               </excludes>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

5.1. Defining Entity Model

First, we will create our Employee entity class annotated with @Entity to tell JPA that this will be mapped to a table in database.

package com.javadevjournal.springbooth2.model;

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;
    String name;
    Double salary;

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

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

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }
}

5.2. Creating Repository Interface

Since we are using spring data JPA starter to our project, we can create a repository interface and extend JpaRepository interface and provide the entity this repository needs to manage, which in this case is Employee along with the type of primary key.

package com.javadevjournal.springbooth2.repository;

import com.javadevjournal.springbooth2.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends JpaRepository < Employee, Integer > {
    
}

5.3. Creating Service

Then we will create our service class which will contain logic to perform CRUD operations to our employee entity.

package com.javadevjournal.springbooth2.service;

import com.javadevjournal.springbooth2.model.Employee;
import com.javadevjournal.springbooth2.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class EmployeeService {

    @Autowired
    EmployeeRepository employeeRepository;

    public List getAllEmployees() {
        List employees = new ArrayList();
        employeeRepository.findAll().forEach(employee - > employees.add(employee));
        return employees;
    }

    public Employee getEmployeeById(int id) {
        return employeeRepository.findById(id).get();
    }

    public void saveOrUpdate(Employee employee) {
        employeeRepository.save(employee);
    }

    public void delete(int id) {
        employeeRepository.deleteById(id);
    }
}

5.4. Rest Controller

To test Spring Boot with H2 Database, let’s create a simple REST controller to test our CURD methods.

package com.javadevjournal.springbooth2.controller;

import com.javadevjournal.springbooth2.model.Employee;
import com.javadevjournal.springbooth2.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @GetMapping("/employees")
    private List getAllEmployees() {
        return employeeService.getAllEmployees();
    }

    @GetMapping("/employees/{id}")
    private Employee getEmployeeById(@PathVariable("id") int id) {
        return employeeService.getEmployeeById(id);
    }

    @PostMapping("/employees")
    private ResponseEntity createEmployee(@RequestBody Employee employee) {
        try {
            employeeService.saveOrUpdate(employee);
        } catch (Exception exception) {
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity("New employee created with id: " + employee.getId(), HttpStatus.CREATED);
    }

    @DeleteMapping("/employees/{id}")
    private ResponseEntity deleteById(@PathVariable("id") int id) {
        try {
            employeeService.delete(id);
        } catch (Exception exception) {
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity("Employee deleted with id: " + id, HttpStatus.OK);
    }
}

6. Running Application

Let’s run our application to see how the overall configuration of H2 database with Spring Boot working.Run our application by hitting run on our main class. The embedded tomcat server will start on default port 8080

Spring Boot with H2

We will start hitting our end points from browser, alternatively, we can use postman.

Spring Boot With H2 Database
Get All Employees
Create New employee- Spring Boot With H2 Database
Create new Employee
Delete Employee
Delete Employee

7. H2 Console With Spring Boot

H2 database has an embedded GUI console for browsing the contents of the database and running queries. To enable H2 console and use it with Spring Boot, we need to add the following property to application.properties: spring.h2.console.enabled=true.Open the URL in the browser and click on the connect to the database.

H2 Console With Spring Boot
H2 Console With Spring Boot

Once connected, we can see the database structure including details of our employee table and the contents which were populated at time of application start up using data.sql script.

Spring Boot With H2 Database

Let’s try to delete an employee using H2 console and delete another employee using the Delete request using POSTMAN.

H2 Console With Spring Boot
Delete an employee using H2 console
H2 Console With Spring Boot

We can see that the employee table is updated and the two rows have been deleted.

Spring Boot With H2 Database

Summary

In this article , we saw how to use Spring Boot With H2 Database. We saw how we can create a spring boot application and configure H2. We also accessed database using H2 console and manipulating data at runtime via our REST APIs.The source code for this article is available on our GitHub Repository.