Integrating H2 Database with Spring Boot

Integrating H2 Database with Spring Boot

Introduction

In this guide, we'll take a look at how to integrate the H2 database with Spring Boot projects.

What is the H2 Database?

H2 is an open-source, Java-based, embedded database. It's very fast and very lightweight. Typically, it's used as an in-memory database which means it stores the data in memory and will not persist data on disk. Although if we need to persist the data, at the flick of a switch - you can persist data as well.

The H2 database is not recommended for production environments and is rather used for proofs of concept, tests, prototypes and similar applications.

Difference Between Persistent and In-Memory Databases

It is worth understanding the difference between persistent and in-memory databases. Persistent databases persist the data in physical memory - that's the entire point of databases. In the case of in-memory databases, data is stored in system memory and data will be lost when the program is closed. In essence - it's just like using RAM to store your objects.

Once the program is closed, the data is lost.

Why use in-memory databases at all then?

In-memory databases are helpful for proofs of concept, as you can easily substitute an in-memory database with a persistent one. It mocks the functionality and backgone of an actual persistent database, while giving you the ease of use and flexibility of performing queries and "persisting" objects, while still being lightweight.

Although H2 does allow you to persist data outside of memory - don't be tempted to replace a more robust database, such as PostgreSQL, MySQL, OracleDB, etc. with it.

Setting up the Spring Boot Project

Let's start out with a skeleton application. The easiest way is to use Spring Initializr and generate a Spring Boot project.

Make sure to add Web, H2 and JPA (Java Persistence API) dependencies.

Again, even though H2 typically isn't used as a persistent database - it mocks classical databases, and it interfaces with the Persistence API.

Clicking on the "Generate Project" button will download the SpringBootH2Integration.zip file, which you can import into your IDE of choice:

Understanding H2's Defaults Configurations

Spring Boot is an opinionated framework and does all the default configurations based on the dependencies available in the classpath.

Since we added H2 as a dependency, Spring Boot knows that in this project we will be connecting to the H2 database, so it auto-configures H2-related properties like the database URL, username, password, etc:

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

If we look at the datasource.url property, the name of the schema is testdb and is an in-memory database (refered to as "mem"). We will see how we can override the default values in upcoming sections.

Overriding H2's Default Configurations

To override any property, just redefine the property with the updated value in the application.properties file available under the src/main/resources folder.

For example, by default H2 console is disabled, so let's enable it by adding below property in the application.properties file:

spring.h2.console.enabled=true

Performing CRUD Operations with H2 in Spring Boot

In the following sections, we are going to create a Person API, which is a simple REST service in which we will interact with H2 using Spring Boot.

If you're not yet familiar with the creation of REST APIs, read our Complete Guide to Building REST APIs with Spring Boot!

The Person API will perform CRUD operations using different endpoints. Below are the details of endpoints:

  1. GET call to /persons will display all person objects available in H2 database.
  2. GET call to /persons/{id} will display the person object with the given id.
  3. POST call to /persons will insert a new person object in the database.
  4. DELETE call to /persons/{id} will delete the person object with the given id from the database.

Before moving further, it makes sense to verify that the project we have created in the previous section is working fine and there are no errors in it.

To verify, run the SpringBootH2IntegrationApplication.java file the way we run any Java program. Doing so, the application will start and we can see the server startup message in the console.

From the console, we can find the URL where we can open the H2 console:

2018-08-18 22:43:30.578  INFO 3792 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Servlet webServlet mapped to [/h2-console/*]

Recall that we did enable the H2 console in the application.properties file.

Let's open the H2 console by typing in http://localhost:8080/h2-console in the browser address bar:

Click connect to log in and see the various options:

You may see different value in the JDBC URL so change the Database URL to jdbc:h2:mem:testdb in the login screen as this is the default URL configured by Spring Boot.

Implementing a REST API with CRUD Functionalities

Finally, let's spin up a simple REST API that performs CRUD operations on a Person entity.

Defining an Entity

Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Naturally, we'll be starting out with our domain model and a definition of the Person model:

@Entity
public class Person {

    @Id
    @GeneratedValue
    private int id;
    private String name;
    private int age;
    private String emailId;

    // Getters and setters
}

Defining a PersonRepository

Utilizing the best of Spring Data JPA - we'll create a really simple, auto-generated CrudRepository for our entities, named PersonRepository:

public interface PersonRepository extends CrudRepository<Person, Integer> {}

Without any further implementation, the PersonRepository has CRUD functionality through save(), findById(), deleteById() and update() methods, which accept any valid Person entity.

Defining a PersonService

Once the repository interface is ready - let's create a concrete service to use the repository to actually perform the reading, writing and updating:

@Service
public class PersonService {

    @Autowired
    PersonRepository personRepository;

    public List<Person> findAll() {
        return personRepository.findAll();
    }

    public Person getPersonById(int id) {
        return personRepository.findById(id).get();
    }

    public void saveOrUpdate(Person person) {
        personRepository.save(person);
    }

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

Defining a PersonController

Finally - to expose the service to end-users, we'll create a @Controller-annotated class, PersonController and expose a few endpoints:

@RestController
public class PersonController {

    @Autowired
    PersonService personService;

    @GetMapping("/persons")
    private List<Person> getAllPersons() {
        return personService.findAll();
    }

    @GetMapping("/persons/{id}")
    private Person getPerson(@PathVariable("id") int id) {
        return personService.getPersonById(id);
    }

    @DeleteMapping("/persons/{id}")
    private void deletePerson(@PathVariable("id") int id) {
        personService.delete(id);
    }

    @PostMapping("/persons")
    private int savePerson(@RequestBody Person person) {
        personService.saveOrUpdate(person);
        return person.getId();
    }
}

Great! We can now test out the functionality of the API and the responses we get.

Testing the Person API

To test the REST service, we'll be using Postman, which can be integrated into the Chrome browser easily using their browser extension or used as a standalone tool.

Test Case 1: Creating a New Person

Using postman, we'll configure a valid POST request for the creation of users:

  1. Set Request Type: POST
  2. Set URL: http://localhost:8080/persons
  3. Set Request Header: Content-Type:application/json
  4. Set Body as: {"name":"person A", "age":23, "emailId": "[email protected]"}
  5. Click "Send"
  6. In the response we will get a personId.

To validate the data inserted in the H2 database:

  1. Open the H2 console
  2. Validate the PERSON table. It will show us the data we have inserted in POST request.

Repeat Test Case 1 with a different person and you'll have two person objects inserted in the database:

Test Case 2: Retrieving the new Person Object

Now, let's try to retrieve one of these users, via their ID. To do this, we'll construct a new request in postman:

  1. Request Type: GET
  2. URL: http://localhost:8080/persons/1
  3. Request Header: Content-Type:application/json
  4. Click "Send"
  5. In response, we will get person data with id 1.

Test Case 3: Deleting a Person Object

Finally, let's try to delete a person from the database:

  1. Request Type: DELETE
  2. URL: http://localhost:8080/persons/1
  3. Request Header: Content-Type:application/json
  4. Click "Send"

After running this, validate that data has been deleted from H2 database:

Conclusion

In this short guide, we've taken a look at how to integrate the in-memory H2 database with Spring Boot, and built a simple REST API around it to showcase the usage.

H2 is a lightweight, embedded database written in Java, typically used for prototyping.

Last Updated: August 25th, 2021
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Want a remote job?

    Prepping for an interview?

    • Improve your skills by solving one coding problem every day
    • Get the solutions the next morning via email
    • Practice on actual problems asked by top companies, like:
     
     
     

    Better understand your data with visualizations

    With over 330+ pages, you'll learn the ins and outs of visualizing data in Python with popular libraries like Matplotlib, Seaborn, Bokeh, and more.

    © 2013-2021 Stack Abuse. All rights reserved.