Spring Boot – Two ways of Inital Test-Data Setup

When developing a application you usually have to have some Mock-Data, for example for your Integration Tests or just to manually check if a functionality is working.
We will bind the initializing of our Mock-Data to the application start.

Preconditions

In this example we are working with the h2 in memory database. I choosed this database because of the easy handling with integration tests. To perform this example I also use JPA. 
So you have to add the following dependencies to your pom.xml

<!--Only add the version if not handled by spring parent--> 
 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
   <version>2.0.3.RELEASE</version>
</dependency>
<dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <scope>runtime</scope>
   <version>1.4.197</version>
</dependency>

The example base on the following entity.

import java.time.LocalDate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 *
 * @author javadevcorner.com
 */
@Entity
public class Hero {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "HERO_NAME")
    private String heroName;
    
    @Column(name = "INSERTION_DATE")
    private LocalDate insertionDate;e;

    //getter, setter and so on...
}

Two ways, one goal

Now, after you have prepaired your project right, let´s start with the two different ways I want to show you today. The first one is by handling the insert of the data via an SQL-Script. The second way will perform the saving actions in a component. So enough of precondition talking, let´s get it on.

SQL Script

The first thing that comes in my mind thinking about databases, is SQL. And, of course, Spring Boot provides a way to insert the data via an SQL Script to our H2 database.

First of all we need to tell our Spring Boot Application that the datasource will be an h2 database. This only has to be done for the SQL-Skript so Spring Boot knows that we´ll have a compatible SQL Database for this script.

application.properties

spring.datasource.platform=h2

application.yml

spring: 
    datasource:
        platform: h2

Implementing the Script

Now we can implement the script.
For this, navigate your your project and src/main/resources and add the fila data-h2.sql.
Open the new file in your IDE (or Editor) and add the following lines

/**
 * Author:  javadevcorner.com
 * Created: 19.06.2018
 */
INSERT INTO hero (ID, HERO_NAME, INSERTION_DATE) VALUES
  (1, 'Son Goku', '2018-06-19'),
  (2, 'Bardock', '2018-06-19');

When you run the application, the Spring Boot Container automatically detect the file and will perform the insert of the data.

Java Bean

The second way performs the input of our data via Java Bean. If you made the example from step 1, please remove the data-h2.sql and the entries in the properties. 

To get started with this art of insertion we need a component that handles the saving actions within the Repository.

import com.example.initDataOnStartup.user.persistence.Hero;
import com.example.initDataOnStartup.user.persistence.HeroRepository;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 *
 * @author javadevcorner.com
 */
@Component
public class HeroMockData {

    @Autowired
    private HeroRepository heroRepository;
    
    public void initMockDataOnStartup() {
        Hero sonGoku = new Hero();
        sonGoku.setHeroName("Son Goku");
        sonGoku.setInsertionDate(LocalDate.now());
        
        Hero bardock = new Hero();
        bardock.setHeroName("Bardock");
        bardock.setInsertionDate(LocalDate.now());
       
        heroRepository.saveAll(Arrays.asList(sonGoku, bardock));
    }
    
}

We just write a simple component. Nothing special about that.
In the initMockDataOnStartup() method we create some new heroes and safe them to our repository.
Have a look at the IDs. We aren´t storing them now. The allocation of this is performed by the annotation of the id attribute in the hero entity. 

Bootstraping the Bean

The last thing we need to do is binding the component to the start up process of the application. To perform this, navigate to your AppStarter class (where your main method belongs to) and modify this method like this:

public static void main(String[] args) {
            ConfigurableApplicationContext cax 
                    = SpringApplication.run(StartUp.class, args);
            cax.getBean(HeroMockData.class).initMockDataOnStartup();
  }

The getBean(Class<T> type) method is expecting a class type.
After the class has been recognized and instantiated in the environment the method we just wrote will be called.

Conclusion

We looked at two different ways to insert data in our h2-database on application start up. The first way was by adding an SQL-Script the second way be adding a Java Bean to the Application Startup. 
For me, the solution performing with an Java Bean is the better way. It is easier to maintain, easier to expand and more intuitive for new developers in a team.

If you know any other ways just let me know them.

 

So thanks for reading and have fun using different ways to insert data on application startup.

Feel free to share

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.