Feb 2, 2021

Loading Local Test Data in Spring Boot

When working on an API, it can be nice to load some data locally on startup. This is especially true when working on a read-only endpoint where no REST API is available to POST any new data. There’s a few different ways to load data in Spring Boot, so this post will walk you through the options and give my preferred approach.

🚀 Your first step is to look at the Spring Boot Docs, where you see that the recommended approach is to use a data.sql file (or import.sql if you have Hibernate ddl-auto manage your tables). So, thinking that’s a good idea, you might write up something like:

merge into MY_OBJECTS values ('e166755b-2b99-43e4-bf64-74ddff84d064', 'abc', '123');
merge into MY_OBJECTS values ('bbe14733-6db7-4f15-ab3a-13fd0e29d397', 'def', '456');
merge into MY_OBJECTS values ('7cebd07b-2334-4c6d-baf9-efe194ae29a5', 'xyz', '789');

⚠️ This works fine for small pieces of data, or for very simple tables, but you’ll notice a few problems that come with this approach:
1) Generated IDs and UUID’s will be complicated
2) Any Spring data validation rules will be missed
3) Enums will not be respected
4) Difficult to reference data from other tables

☕ Then maybe, like me, you miss the Grails way of having a Bootstrap.groovy class that gets magically called at system startup? Grails would run this script file after startup before serving the application, and it was a great place to add test local data.

And this is how I felt for a long time, that Spring Boot just didn’t have an easy way to do something similar. Until I had a Twitter conversation, where it was shown to me about using an ApplicationRunner.java class.

But interestingly when I dove back into the Spring Docs to find more info, there’s really only an obscure reference to ApplicationRunner.java, and even then there isn’t an example of how to use it.

📝 So here’s my take at using ApplicationRunner to bootstrap some SpringBoot data:

This fixes all of my complaints about data.sql from above:
1) The ID is not specified, so UUID will get auto-generated
2) It uses the Repository class to save, along with using an Entity Validations
3) If this class needed to use an Enum we could easily reference it
4) We can do other table operations first, like only insert the data if the table is empty

❗Note a couple of other things:
A) The @Profile annotation specifies to only run this for the local and test profiles. These are fairly common custom profiles to have, but you’ll need to setup your application to use these (or others) if you don’t have them already.
B) I’m using Lombok to auto generate the constructor. You don’t have to use Lombok, if you love typing lots of boilerplate, so you can remove that annotation and write your own constructor.

This certainly isn’t for every application, so just take it as a tool to add to your toolbox. But I’m mostly writing this because I was surprised that the concept was around for many years now and somehow I had just never stumbled upon it, until now!

About the Author

Jeff Sheets profile.

Jeff Sheets

VP - Technology

Jeff has developed Java, Groovy, Grails, and Javascript web apps for industries as varied as Defense, Energy, Weather, Insurance, and Telecom. He is a co-organizer of the Omaha Java Users Group. Jeff has worked on Grails projects since the Grails 1.3.x days, and has experience with production Groovy code as well as Spock tests and Gradle builds. His latest focus has been on AngularJS and Spring Boot applications using JHipster. Jeff also enjoys volunteering at local CoderDojo events to teach programming to our next generation.

Leave a Reply

Your email address will not be published.

Related Blog Posts
Building Better Data Visualization Experiences: Part 1 of 2
Through direct experience with data scientists, business analysts, lab technicians, as well as other UX professionals, I have found that we need a better understanding of the people who will be using our data visualization products in order to build them. Creating a product utilizing data with the goal of providing insight is fundamentally different from a typical user-centric web experience, although traditional UX process methods can help.
Kafka Schema Evolution With Java Spring Boot and Protobuf
In this blog I will be demonstrating Kafka schema evolution with Java, Spring Boot and Protobuf.  This app is for tutorial purposes, so there will be instances where a refactor could happen. I tried to […]
Redis Bitmaps: Storing state in small places
Redis is a popular open source in-memory data store that supports all kinds of abstract data structures. In this post and in an accompanying example Java project, I am going to explore two great use […]
Let’s build a WordPress & Kernel updated AMI with Packer
First, let’s start with What is an AMI? An Amazon Machine Image (AMI) is a master image for the creation of virtual servers in an AWS environment. The machine images are like templates that are configured with […]