Spring Boot + Spring Batch + MySQL Hello World Example | CodeUsingJava

Spring Boot + Spring Batch + MySQL Hello World Example

What is Batch Processing

Let us first have a look at what is meant by Batch Processing and where it is used. Batch Processing is a very old concept. Older than Spring Framework itself. Batch processing can be defined as processing of large amount of data in an automated way without any external intervention. Let us take a look at some scenarios where Batch Processing is used -
  • Every day in the evening you receive a statement of the stocks you have traded. After the market closes for the day, a batch job runs that processes all the day's transactions and creates this statement which is then mailed you.
  • Big Data requires to process a large amount of data. This data can be provided to Big Data using Batch Jobs.
  • During Migration large amount of data is to be moved from one physical location to another.

Video Tutorial

What is Spring Batch

Spring Batch is an open source framework for batch processing. It is a lightweight, comprehensive solution designed to enable the development of robust batch applications, which are often found in modern enterprise systems. Spring Batch builds upon the POJO-based development approach of the Spring Framework.
Before we begin the implementation let us understand some concepts of Spring Batch. Any work that we want to accomplish using Spring Batch is called a Job. So suppose we want to create an End of Day Stock Transaction Statement, then this will be called a Spring Batch Job. To complete this Job we break it's implementation into Steps. For example for creation of End of Day Statement Job can be broken into -
  • Fetch all the Buys for a particular customer
  • Fetch all the Sells for a particular customer
  • Perform some calculation
  • Send it to the customer
We start/launch a job using the job launcher. Also all the information about the job i.e whether or not the job has started, If started what is it's state, if failed till where did it execute and then failed etc. are stored in JobRespository which are tables automatically created by Spring Batch.
Spring Boot + Batch Hello World Example
In Spring Batch, Steps can be of two types-
Spring Boot + Batch Tasklet
  • Tasklet based step- Tasklets are used when we want to perform a single task within a step
  • Chunk based step - Chunks read a chunk of data and then perform 3 tasks on this chunk -
    • Item Reader
    • Item Processor
    • Item Writer
For this example we will be creating a Job with single Tasklet Step which prints Hello World. We will making use of MySQL database for creating JobRepository table. We will be looking at the JobRepository tables created and their use.
Spring Boot + Batch Example

Implementation

In this example we will be creating a Spring Batch Application which will have a single tasklet that simply prints hello world to the screen.

Technology Stack

We will be making use of-
  • Java 1.8
  • Spring Boot
  • Spring Batch
  • Spring JDBC
  • Maven
  • MySQL
We will be creating a Maven Project as follows-
Spring Boot + Batch Maven
The pom.xml will be as follows-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.codeusingjava</groupId>
	<artifactId>boot-batch</artifactId>
	<version>0.0.1-SNAPSHOT</version>


	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-batch</artifactId>
		</dependency>
		
	</dependencies>

</project>
Create the Spring Boot Bootstrap class as follows-
package com.codeusingjava;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootBatch {

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

}

Create the Spring Batch Configuration file. This class we willbe making use of the annotation EnableBatchProcessing. The @EnableBatchProcessing annotation enables Spring Batch features and the needed dependencies.
package com.codeusingjava.config;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {

	@Autowired
	public JobBuilderFactory jobBuilderFactory;

	@Autowired
	public StepBuilderFactory stepBuilderFactory;

	@Bean
	public Step helloWorldStep() {
		return stepBuilderFactory.get("helloWorldStep").tasklet(new Tasklet() {

			public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {
				System.out.println("Hello World Step");
				return RepeatStatus.FINISHED;
			}
		}).build();
	}

	@Bean
	public Job helloWorldJob() {
		return jobBuilderFactory.get("helloWorldJob").start(helloWorldStep()).build();

	}
}
If we now run the application we get the following exception
Spring Boot + Batch Error
It is because we need to specify some database for storing the Job metadata. We will be making use of MySQL database for this.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.codeusingjava</groupId>
	<artifactId>boot-batch</artifactId>
	<version>0.0.1-SNAPSHOT</version>


	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-batch</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		
	</dependencies>

</project>
We now define the mysql properties in the application.properties configuration file. Do remember to set the spring.batch.initialize-schema to Always. If not done the application will not start as the Spring Batch Job Metadata tables do not get created by default.
spring.datasource.url=jdbc:mysql://localhost/bootbatch?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.platform=mysql
spring.datasource.initialization-mode=always
spring.batch.initialize-schema=ALWAYS
Now start the application-
Spring Boot + Batch Run
In the mysql database we can see the following tables are created in the bootbatch db-
Spring Boot + Batch MySQL Tables
The tables are as follows-
Spring Boot + Batch Tables
Go to Batch Instance Table-
Spring Boot + Batch Instance Table
Go to Batch Execution Table-
Spring Boot + Batch Execution Table

Downloads-

Spring Boot + Spring Batch Hello World Example