## Integrating H2 Database with Spring Boot

### What is Spring Boot

If you are a Spring developer, surely you are familiar with the overhead of repetitive configurations we need to do in order to set up a project. Honestly, it's a painful and tedious activity. Being a developer, our focus should be on business logic and not setting up and configuring the project.

The solution to this problem is Spring Boot which according to official documentation on spring.io:

"Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can just run"

Let's break it down a bit and explain the meaning of the definition:

• stand-alone – Spring Boot, by default supports a variety of embedded web servers which runs inside the application. This eliminates the need of deployment of any war files. It is important to understand that here the word "stand-alone" does not mean Java standard application.
• production-grade – Spring Boot applications are high quality and can be deployed to production as is.
• just run – Spring Boot applications can be simply run using the main function OR using the java –jar command. There is no need to deploy it to external web servers - though we are free to do so if needed.

Another powerful feature of Spring Boot is that it is a so-called "opinionated" framework. As mentioned earlier, developing a traditional Spring application requires a lot of configuration. These configurations don't change much over time so they end up being boilerplate code.

Spring Boot auto-configures all of the configurations by default based on the dependencies present/available in the classpath. Of course, you can re-configure or change these configurations if need be.

### What is the H2 Database?

H2 is an open source database and is written in Java. It is very fast and of very small size. It is primarily 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, it supports that as well.

The H2 database is not recommended for production environments and is ideal for a quick PoC kind of project where there is a need for a simple database.

It can be easily integrated with Spring which we are going to look at in this tutorial.

### 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 so that it is available even if the database server is bounced. In the case of in-memory databases, data is stored in system memory and data will be lost when the program is closed.

In-memory databases are quite helpful for PoCs and are not recommended for use in production applications.

Popular persistent databases include Oracle, MySQL, Postgres, etc., whereas H2 is commonly used as the in-memory database.

### Setting up the Spring Boot Project

There are two ways we can create a Spring Boot project, and in this section, we are going to discuss both ways so that we can become familiar with both approaches:

#### 1. Spring Initializr

Spring Initializr is a convenient way of generating Spring Boot projects and is managed by spring.io. This helps to generate a Spring Boot project online, without needing to download any tools.

Open the start.spring.io URL in your browser and enter the required details. Make sure to add Web, H2 and JPA dependencies, as these libraries will be needed for our project.

Clicking on "Generate Project" button will download the SpringBootH2Integration.zip file.

Extracted zip file can be easily imported as "Existing Maven Project" in Eclipse

#### 2. Spring Tool Suite

Spring Tool Suite (also known as STS) is an IDE built on top of Eclipse and is the most common way to generate a project.

Spring Boot projects can be created using "New Spring Starter Project" option. This will open a new window where we need to enter mandatory information. Make sure to add Web, H2 and JPA as dependencies as these libraries will be needed for our project.

### Understanding H2's Defaults Configurations

As I mentioned earlier, 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.

The following are the default configurations set by Spring Boot:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
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

In the previous section we saw the default configurations of H2 which can be easily changed or overridden on a need basis, and this is the beauty of Spring Boot.

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


### Example Overview (Person API)

In the next 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.

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:

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 Person API Example

It's the time to write the code using what we have discussed.

#### Defining an Entity

We will be performing CRUD operations on a Person object. Let's define it with only four attributes to keep it simple:

@Entity
public class Person {

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

//getters and setters
}


#### Defining PersonRepository

As we are using JPA in this example to interact with the database, so let's define PersonRepository:

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


#### Defining PersonService

PersonService will be exposing methods that will be called from the controller which interact with the repository:

@Service
public class PersonService {

@Autowired
PersonRepository personRepository;

public List<Person> getAllPersons() {
List<Person> persons = new ArrayList<Person>();
return persons;
}

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 PersonController

PersonController will write controller methods that will be called by different endpoints calls:

@RestController
public class PersonController {

@Autowired
PersonService personService;

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

@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();
}
}


So we have completed the implementation of our Person API example and now it's time to test it and validate the data in the H2 database.

### Testing the Person API

To test the REST service, I am going to use the POSTMAN tool, which can be integrated into the Chrome browser easily using their browser extension.

Let's start the application by running SpringBootH2IntegrationApplication.java. The output in the console should look something like this. This confirms that it has correctly started:

2018-08-19 17:00:32.571  INFO 472 --- [   main] c.t.h.SpringBootH2IntegrationApplication : Started SpringBootH2IntegrationApplication in 14.885 seconds (JVM running for 16.437)


#### Test Case 1: Creating new Person Object

Open using Postman

1. Set Request Type: POST
2. Set URL: http://localhost:8080/persons
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 so that we will now have two person objects inserted in the database.

#### Test Case 2: Retrieving the new Person Object

Open Postman

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

#### Test Case 3: Deleting a Person Object

Open Postman

1. Request Type: DELETE
2. URL: http://localhost:8080/persons/1