Reputation: 712
I am building a Spring Boot application (version 2.7.7) to dump data from .csv to MySQL db. I am getting several exceptions on building the project.
application.properties-
spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/batch_db
spring.datasource.username=hbstudent
spring.datasource.password=hbstudent
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
server.port=8081
spring.batch.jdbc.initialize-schema=always
#to initalize the tables
Batch Configuration-
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired
private DataSource dataSource;
@Bean
public FlatFileItemReader<User> reader(){
FlatFileItemReader<User> reader=new FlatFileItemReader<>();
reader.setResource(new ClassPathResource("records.csv"));
reader.setLineMapper(getLineMapper()); //how to map the line which is read.
reader.setLinesToSkip(1); // skip lines when error occurs
return reader;
}
private LineMapper<User> getLineMapper() {
DefaultLineMapper<User> lineMapper=new DefaultLineMapper<>();
DelimitedLineTokenizer delimitedLineTokenizer=new DelimitedLineTokenizer();
delimitedLineTokenizer.setNames(new String[]{"Roll Number","Name of Student","Personal Email ID","Email ID","MOBILE NO"});
delimitedLineTokenizer.setIncludedFields(new int[]{1,2,3,4,5});
BeanWrapperFieldSetMapper<User> fieldSetMapper=new BeanWrapperFieldSetMapper<>();
fieldSetMapper.setTargetType(User.class);
lineMapper.setLineTokenizer(delimitedLineTokenizer);
lineMapper.setFieldSetMapper(fieldSetMapper);
return lineMapper;
}
@Bean
public UserItemProcessor processor(){
return new UserItemProcessor();
}
@Bean
public JdbcBatchItemWriter<User> writer(){
JdbcBatchItemWriter<User> writer= new JdbcBatchItemWriter<>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<User>());
writer.setSql("insert into user(rollNo,name,personalEmail,officialEmail,mobileNo) values (:rollNo,:name,:personalEmail,:officalEmail,:mobileNo)");
writer.setDataSource(dataSource);
return writer;
}
@Bean
public Job importUserJob(){
return new JobBuilder("USER_IMPORT_JOB")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
@Bean
public Step step1(){
return new StepBuilder("Step 1")
.<User,User>chunk(5)
.reader(reader())
.writer(writer())
.build();
}
}
On building the project I am getting the following exceptions-
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.example.spring_boot_batch_demo.SpringBootBatchDemoApplication]; nested exception is java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration$DataSourceInitializerConfiguration
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:609) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassParser.access$800(ConfigurationClassParser.java:110) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:812) ~[spring-context-5.3.24.jar:5.3.24]
at java.base/java.util.ArrayList.forEach(Unknown Source) ~[na:na]
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:809) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:780) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:192) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.7.7.jar:2.7.7]
at com.example.spring_boot_batch_demo.SpringBootBatchDemoApplication.main(SpringBootBatchDemoApplication.java:10) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.7.7.jar:2.7.7]
Caused by: java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration$DataSourceInitializerConfiguration
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-2.7.7.jar:2.7.7]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:225) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassParser.processMemberClasses(ConfigurationClassParser.java:371) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:271) ~[spring-context-5.3.24.jar:5.3.24]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:249) ~[spring-context-5.399) ~[spring-context-5.3.24.jar:5.3.24]
... 24 common frames omittedCaused by: java.lang.IllegalArgumentException: No enum constant org.springframework.boot.sql.init.DatabaseInitializationMode.ALWAYS
at java.base/java.lang.Enum.valueOf(Unknown Source) ~[na:na]
at org.springframework.boot.sql.init.DatabaseInitializationMode.valueOf(DatabaseInitializationMode.java:26) ~[spring-boot-2.7.7.jar:2.7.7]
at org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition.getDatabaseInitializationMode(OnDatabaseInitializationCondition.java:75) ~[spring-boot-autoconfigure-2.7.7.jar:2.7.7]
at org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition.getMatchOutcome(OnDatabaseInitializationCondition.java:60) ~[spring-boot-autoconfigure-2.7.7.jar:2.7.7]
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.7.7.jar:2.7.7]
... 30 common frames omitted
For referred several other posts which stated versioning problem, but it didn't help. I cannot find the problem with the code, can somebody help me?
Upvotes: 1
Views: 805
Reputation: 988
I have analysed your code, Here are my findings.
BatchConfig
class. You are using new JobBuilder()
, new StepBuilder()
while creating Job and Step. The right way is to use JobBuilderFactory
, StepBuilderFactory
.PS: I tested with PostgreSQL database using these properties but I am sure it will work with MySQL database as well
application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/batch_db
spring.datasource.username=root
spring.datasource.password=admin
#show the queries in the console
spring.jpa.show-sql=true
#to format the queries for readability
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
server.port=8081
spring.batch.jdbc.initialize-schema=always
#spring.batch.job.enabled=false
#to initalize the tables
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ayushsingh</groupId>
<artifactId>spring_boot_batch_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring_boot_batch_demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.mysql</groupId>-->
<!-- <artifactId>mysql-connector-j</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
BatchConfig
package com.ayushsingh.spring_boot_batch_demo.config;
import com.ayushsingh.spring_boot_batch_demo.entities.User;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
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.launch.support.RunIdIncrementer;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import javax.sql.DataSource;
@Configuration //this is important- enables batch processing in the project
@EnableBatchProcessing
public class BatchConfig {
@Autowired
private DataSource dataSource;
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public FlatFileItemReader<User> reader(){
FlatFileItemReader<User> reader=new FlatFileItemReader<>();
reader.setResource(new ClassPathResource("records.csv"));
reader.setLineMapper(getLineMapper()); //how to map the line which is read.
reader.setLinesToSkip(1); // skip lines when error occurs
return reader;
}
private LineMapper<User> getLineMapper() {
DefaultLineMapper<User> lineMapper=new DefaultLineMapper<>();
DelimitedLineTokenizer delimitedLineTokenizer=new DelimitedLineTokenizer();
delimitedLineTokenizer.setNames(new String[]{"Roll Number","Name of Student","Personal Email ID","SMVDU Email ID","MOBILE NO"});
delimitedLineTokenizer.setIncludedFields(new int[]{1,2,3,4,5});
BeanWrapperFieldSetMapper<User> fieldSetMapper=new BeanWrapperFieldSetMapper<>();
fieldSetMapper.setTargetType(User.class);
lineMapper.setLineTokenizer(delimitedLineTokenizer);
lineMapper.setFieldSetMapper(fieldSetMapper);
return lineMapper;
}
@Bean
public UserItemProcessor processor(){
return new UserItemProcessor();
}
@Bean
public JdbcBatchItemWriter<User> writer(){
JdbcBatchItemWriter<User> writer= new JdbcBatchItemWriter<>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<User>());
writer.setSql("insert into user(rollNo,name,personalEmail,officialEmail,mobileNo) values (:rollNo,:name,:personalEmail,:officalEmail,:mobileNo)");
writer.setDataSource(dataSource);
return writer;
}
@Bean
public Job importUserJob(){
return jobBuilderFactory.get("USER_IMPORT_JOB")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
@Bean
public Step step1(){
return stepBuilderFactory.get("Step 1")
.<User,User>chunk(5)
.reader(reader())
.writer(writer())
.build();
}
}
Upvotes: 1