Spring Boot H2 Database is an extremely useful tool in the arsenal of any developer working on a Spring Boot application.

H2 database is a java in-memory database that allows you, as a developer, a large amount of freedom to work with database changes during development phase.

The Spring Boot H2 database can be embedded within a Java application or could also be run in client-server mode. It is also very useful during development phase for iterating through schema changes without worrying about making changes to the actual database such as MySQL or PostgreSQL.

To recap things, we looked at the Spring Boot Startup process, in the last post. Also, we took a high-level view of the various dependencies.

In this post, we will take our first step towards building production-ready Spring Boot Microservices. But for that, we will first learn the process of setting up Spring Boot H2 database.

Spring Boot H2 Database – The Required Dependencies

The main dependencies to enable H2 database in our Spring Boot application are as follows:

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
		<groupId>com.h2database</groupId>
		<artifactId>h2</artifactId>
		<scope>runtime</scope>
</dependency>

Spring Boot Starter Data JPA pulls in Hibernate and JPA dependencies. But apart from these two, Spring Data JPA also provides several interfaces that make it super easy to build repositories.

H2 database pulls in support for H2 Spring Boot such as the data source, H2 console and drivers required to run it.

Declaring an Entity

An Entity is a Java class representation of a database table. The way it works is that you define a class in Java and annotate it with appropriate annotations. After that, Hibernate kicks in and takes care of mapping the objects to the underlying relational model.

Let’s see how we do that.

@Entity
@Table(name = "vehicle")
public class Vehicle {

    @Id
    private UUID id;

    private String vehicleIdentityNumber;

    private String make;

    private String model;

    public Vehicle() {
    }

    public UUID getId() {
        return id;
    }

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

    public String getVehicleIdentityNumber() {
        return vehicleIdentityNumber;
    }

    public void setVehicleIdentityNumber(String vehicleIdentityNumber) {
        this.vehicleIdentityNumber = vehicleIdentityNumber;
    }

    public String getMake() {
        return make;
    }

    public void setMake(String make) {
        this.make = make;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    @Override
    public String toString() {
        return "Vehicle{" +
                "id=" + id +
                ", vehicleIdentityNumber='" + vehicleIdentityNumber + '\'' +
                ", make='" + make + '\'' +
                ", model='" + model + '\'' +
                '}';
    }
}

The Vehicle class is annotated with @Entity annotation. This annotation basically tells JPA that this class should be mapped to its own table. In other words, @Entity is a type of marker interface similar to Serializable in Java.

Also, if we need more fine-grained control over the name of the table, we can use @Table annotation. However, the @Table annotation is not mandatory. Basically, if we don’t specify it, JPA will use the class name as the table name.

Next important bit to note here is the use of @Id annotation. An entity should have at least one Id field. Also, this will act as a primary key for the table. In our case, we have declared this Id field as a UUID.

This is almost enough to get up and running with a basic H2 Spring Boot configuration. However, to see something tangible, there are some more configuration settings.

Enabling the Spring Boot H2 Database Console View

Spring Boot H2 also provides a console view that can be used to see the tables created as well as the data inserted. It’s a pretty handy feature to see your persistence logic in action. Also, you can inspect the data in the h2 console view allowing you to test your application locally.

To enable the H2 console view, open the application.properties file in your application’s resources folder. Then, add the below statements in the file:

#H2 settings
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

The above statements are pretty self-explanatory. The first one enables h2 console whereas, the second statement defines the path on which the console would be accessible.

Run the application now. And visit http://localhost:8080/h2-console

Note the JDBC URL. If you have used Spring Boot H2 the first time, you might see a different URL. However, in such a case, you should change it to the one shown in the picture above where we are trying to connect to testdb. Also, you can leave the default user name and password as it is.

Click Connect. After this, you would be able to see the h2 console view. Basically, if you’ve followed the steps in this article, you should see a Vehicle table. Also, this table should have all the fields defined in the Entity class.

Right now, the table wold be empty because we haven’t inserted any records.

Controlling the H2 Database Properties

You might have a requirement to control the URL and other parameters for your H2 console. Basically, this is useful if you have a need to use the same H2 database in multiple Spring Boot applications.

In that case, you can specify some more settings in the application.properties file as below:

#H2 settings
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

spring.datasource.url=jdbc:h2:mem:mytestdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create

Now, start-up the Spring Boot application again and navigate to http://localhost:8080/h2-console

This time you will need to change the JDBC URL to the one you specified in the application.properties.

Note that we changed the URL to point to mytestdb instead of the default value.

You can now click Connect and see the Spring Boot H2 schema and tables as before.

With this we have basically completed setting up Spring Boot H2 Database for a sample application.

Inserting Records to Table using Spring Boot

We will see how inserting records to table using Spring Boot looks like. As we do this, we will also add some functionality to our sample application.

To achieve our goal of inserting records, we will be using the repository interfaces provided by Spring Data JPA.

Spring Data JPA provides powerful abstractions that allows developers to get away from writing boilerplate code to setup tables. In order to create/read/update/delete records, all they have to do is wire up the entity with an appropriate interface.

We have already included the dependency in the pom.xml file. See below:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Defining the Repository Interface

In the next step, we need to declare repository interface for our entity. Above all other features, this interface will act as a bridge between the Java class and the actual table in the database.

We want to keep all our repository interfaces in one place. So we will create new package called repositories under the base package. Inside this package we will create the interface and name it VehicleRepository.

package com.favtuts.demo.sbstarter.repositories;

import com.favtuts.demo.sbstarter.entities.Vehicle;
import org.springframework.data.repository.CrudRepository;

import java.util.UUID;

public interface VehicleRepository extends CrudRepository<Vehicle, UUID> {
}

Note what we are doing here.

We are extending the CrudRepository interface provided by Spring Data JPA. In other words, we are gettting CRUD operations for free. CRUD stands for Create, Read, Update, Delete.

Now that we’ve declared the interface, we can actually insert some records into our H2 database.

Command Line Runner

Spring Boot provides two interfaces that can be used to run specific pieces of code when an application starts up.

Command Line Runner is one such interface. Using this interface, we can write some logic that gets executed at the application start-up time. This approach is also used to bootstrap test data.

In the main class where we have the @SpringBootStarterApplication annotation, we can declare a class that implements CommandLineRunner interface. Then, we implement it’s run method and insert two vehicles in the Vehicle table.

See below code:

package com.favtuts.demo.sbstarter;

import com.favtuts.demo.sbstarter.entities.Vehicle;
import com.favtuts.demo.sbstarter.repositories.VehicleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;

import java.util.UUID;

@SpringBootApplication
public class SpringBootStarterAppApplication {

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

}

@Component
class DemoCommandLineRunner implements CommandLineRunner {

	@Autowired
	private VehicleRepository vehicleRepository;

	@Override
	public void run(String... args) throws Exception {

		Vehicle audi = new Vehicle();
		audi.setId(UUID.randomUUID());
		audi.setVehicleIdentityNumber("Reg#1234");
		audi.setMake("Audi");
		audi.setModel("Q5");

		vehicleRepository.save(audi);

		Vehicle tesla = new Vehicle();
		tesla.setId(UUID.randomUUID());
		tesla.setVehicleIdentityNumber("Reg#6789");
		tesla.setMake("Tesla");
		tesla.setModel("Model S");

		vehicleRepository.save(tesla);
	}
}

Some important things to note:

  • We have placed @Component annotation on DemoCommandLineRunner class. This registers the class as a component. It also instructs Spring to create a bean for this class.
  • We have placed @Autowired annotation above the VehicleRepository. This tells Spring that an instance of the repository class needs to be injected as a dependency to DemoCommandLineRunner. There are various ways of dependency injection. However, using Autowired is the most explicit.
  • The VehicleRepository provides a save() method. The save() method is part of CrudRepository interface. It also expects an object of managed entity as an input parameter.

When the Spring context loads up, the CommandLineRunner should be executed. And the two records should be inserted into the table. However, to make sure, let’s check it out.

Run the application. Once it starts up successfully, visit the h2-console path. Then, once you connect to the database, you should be able to query the Vehicle table. As you can see in the below screenshot, the two vehicles we added are now stored in the database.

The Next Step

Even though this approach works well for testing, it doesn’t go well with the needs of a real application.

In a real application, we would often be having some functionality where users should be able to create new records. Or update them. Or delete them. In other words, we need a way for users to interact with our database. In order to do so, we will expose our resources or model entities (in this case Vehicle) as REST resources.

We will start off on that in the next Exposing repositories as REST resources using Spring Boot.

Download Source Code

$ git clone https://github.com/favtuts/java-spring-boot-microservices/tree/setup-h2-database
$ cd java-spring-boot-microservices/sources/spring-boot-starter-app
$ mvn clean package spring-boot:run

Leave a Reply

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