2

I am using springboot 2.6.6 with mysql and quite new to springbatch. I was getting an error "spring context is forming a cycle" when I kept the datasource in the same config file where readers and writers are kept in SampleJob.java. Suggested solution was to put the datasource in another class so I placed the datasource within the same class as main(). Now I am getting this issue:

Error

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.batch.BatchDataSourceScriptDatabaseInitializer]: Factory method 'batchDataSourceInitializer' threw exception; nested exception is java.lang.IllegalStateException: Unable to detect database type
Caused by: java.lang.IllegalStateException: Unable to detect database type

SampleJob.java

@Configuration
public class SampleJob {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;
            

    @Bean
    public Job chunkJob() {
        return jobBuilderFactory.get("Chunk Job")
                .incrementer(new RunIdIncrementer())
                .start(firstChunkStep())
                .build();
    }
    
    

    private Step firstChunkStep() {
        return stepBuilderFactory.get("First Chunk Step")
                .<StudentJdbc, StudentJdbc>chunk(3)
                  .reader(jdbcItemReader())
                  
                .writer(flatFileItemWriter(null))
                .build();
    }

    
    @Bean
    @StepScope
    public JdbcCursorItemReader<StudentJdbc> jdbcItemReader(){

        JdbcCursorItemReader<StudentJdbc> jdbcReader = new JdbcCursorItemReader<StudentJdbc>();
        jdbcReader.setSql("select id, first_name as firstName, last_name as lastName, email from students");
        
        jdbcReader.setDataSource(universitydatasource());
        jdbcReader.setRowMapper(new BeanPropertyRowMapper<StudentJdbc>() {
            {
                setMappedClass(StudentJdbc.class);
            }
        });
    
        return jdbcReader;
    }
    

    @StepScope
    @Bean
    public FlatFileItemWriter<StudentJdbc> flatFileItemWriter(
            @Value("#{jobParameters['outputFile']}") FileSystemResource fileSystemResource
    ){
        FlatFileItemWriter<StudentJdbc> flatFileItemWriter = new FlatFileItemWriter<StudentJdbc>();
        flatFileItemWriter.setResource(fileSystemResource);
        
        flatFileItemWriter.setResource(fileSystemResource);
        
        flatFileItemWriter.setHeaderCallback(new FlatFileHeaderCallback() {
            
            @Override
            public void writeHeader(Writer writer) throws IOException {
                writer.write("Id, First Name, Last Name, Email");
            }
        });
            
        flatFileItemWriter.setLineAggregator(new DelimitedLineAggregator(){
            {
                setFieldExtractor(new BeanWrapperFieldExtractor<StudentResponse>() {
                    {
                        setNames(new String[] {"id","firstName","lastName","email"});
                    }
                    
                });
            }
        });
        
        flatFileItemWriter.setFooterCallback(new FlatFileFooterCallback() {
            
            @Override
            public void writeFooter(Writer writer) throws IOException {
                writer.write("Created @ "+new Date());
            }
        }); 
        
        return flatFileItemWriter;
    }
}

Main class file

@SpringBootApplication
@EnableBatchProcessing
public class ChunksApplication {

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

    @Bean
    @Primary    
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource datasource() {
        return DataSourceBuilder.create().build();
    }
    
    
    @Bean
    @ConfigurationProperties(prefix="spring.universitydatasource")
    public DataSource universitydatasource() {
        return DataSourceBuilder.create().build();
    }
}

application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/udemy-springbatch-chunks
spring.datasource.username=____
spring.datasource.password=____
spring.datasource.platform=mysql
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver


#alternate datasource for db input for reader
spring.universitydatasource.url=jdbc:mysql://localhost:3306/university?createDatabaseIfNotExist=true
spring.universitydatasource.username=____
spring.universitydatasource.password=____
spring.universitydatasource.platform=mysql
spring.universitydatasource.driverClassName=com.mysql.cj.jdbc.Driver

3 Answers 3

4

Found the solution. It seems that @ConfigurationProperties weren't picking up the url, username and password from application.properties so this worked in the main class file itself:

@Bean
@Primary    
public DataSource datasource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
    dataSourceBuilder.url("jdbc:mysql://localhost:3306/udemy-springbatch-chunks");
    dataSourceBuilder.username("____");
    dataSourceBuilder.password("____");
    return dataSourceBuilder.build();
}


@Bean("universityDatasource")
public DataSource universitydatasource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
    dataSourceBuilder.url("jdbc:mysql://localhost:3306/university?createDatabaseIfNotExist=true");
    dataSourceBuilder.username("____");
    dataSourceBuilder.password("____");
    return dataSourceBuilder.build();
}
Sign up to request clarification or add additional context in comments.

Comments

1

It works for me

spring.batch.schema=classpath:org/springframework/batch/core/schema-mysql.sql

Comments

0

My solution was this, you have to add the jdbcUrl

Properties file example:

spring.datasource.url=jdbc:mysql://localhost:3306/udemy-springbatch-chunks
spring.datasource.jdbcUrl=${spring.datasource.url}
spring.datasource.username=____
spring.datasource.password=____
spring.datasource.platform=mysql
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver


#alternate datasource for db input for reader

spring.universitydatasource.url=jdbc:mysql://localhost:3306/university
spring.universitydatasource.jdbcUrl=${spring.universitydatasource.url}
spring.universitydatasource.username=____
spring.universitydatasource.password=____
spring.universitydatasource.platform=mysql
spring.universitydatasource.driverClassName=com.mysql.cj.jdbc.Driver

Regards.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.