1
\$\begingroup\$

I am newbie to Spring Framework. I am trying to move table data from one vendor database to another vendor database using Spring Boot + Spring Batch. I am looking for feedback if this correct approach to solve my particular problem. As part of data transfer process, I have created 3 tables like below

Tables

  • project_preprocess
  • project_main
  • project_backup

Then, I created a Spring Batch job that performs below steps -

  1. Delete data in project_preprocess table
  2. Copy data into project_preprocess table from source database
  3. Take backup of project_main in project_backup
  4. Delete data from project_main
  5. Copy data from project_preprocess into project_main

My code that attempts to accomplish above task is below. Please let me know if this is Spring-way to implement.

@Configuration
@EnableBatchProcessing
public class BatchConfiguration2 {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired 
    public DataSourceConfigs dataSource;

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }

    @Bean
    public JobExplorer jobExplorer() throws Exception {
        MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(mapJobRepositoryFactoryBean());
        jobExplorerFactory.afterPropertiesSet();
        return jobExplorerFactory.getObject();
    }

    @Bean
    public MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean() {
        MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean();
        mapJobRepositoryFactoryBean.setTransactionManager(transactionManager());
        return mapJobRepositoryFactoryBean;
    }

    @Bean
    public JobRepository jobRepository() throws Exception {
        return mapJobRepositoryFactoryBean().getObject();
    }

    @Bean
    public JobLauncher jobLauncher() throws Exception {
        SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
        simpleJobLauncher.setJobRepository(jobRepository());
        return simpleJobLauncher;
    }



    public ItemReader<Project> reader(DataSource datasource) {
        JdbcCursorItemReader<Project> reader = new JdbcCursorItemReader<Project>();
        reader.setDataSource(datasource);
        reader.setName("project-reader");
        reader.setSql("SELECT id, name, description, creationDate, createdBy FROM dbo.project");
        reader.setRowMapper(new BeanPropertyRowMapper<>(Project.class));
        reader.setFetchSize(100);
        return reader;      
    }

    @Bean
    public ProjectItemProcessor processor() {
        return new ProjectItemProcessor();
    }


    public ItemWriter<Project> jdbcWriter(DataSource ds, ItemPreparedStatementSetter<Project> setter) {



        JdbcBatchItemWriter<Project> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(ds);           
        writer.setSql("INSERT INTO dbo.project_preprocess(id, name, description, creation_date, created_by, data_source_id) VALUES(?,?,?,?,?,?);");
        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.setItemPreparedStatementSetter(setter);

        return writer;

    }

    @Bean
    public ItemPreparedStatementSetter<Project> setter() {
        return (item, ps) -> {
            ps.setInt(1, item.getId());
            ps.setString(2, item.getName());
            ps.setString(3, item.getDescription());
            ps.setString(4, item.getCreationDate());
            ps.setString(5, item.getCreatedBy());
            ps.setInt(6, 1);
        };
    }


    @Bean
    public Job importProjectTableJob(JobCompletionNotificationListener listener) {
        return jobBuilderFactory.get("importFortifyProjectTable")
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .start(databaseOpsTasklet("DELETE FROM dbo.project_preprocess"))
                .next(loadIntoProcessingTable())
                .next(databaseOpsTasklet("INSERT INTO dbo.project_backup SELECT * FROM dbo.project_main"))
                .next(databaseOpsTasklet("DELETE FROM dbo.project_main"))
                .next(databaseOpsTasklet("INSERT INTO dbo.project_main SELECT * FROM dbo.project_preprocess"))                
                .build();
    }

    public Step databaseOpsTasklet(String sql){
        return stepBuilderFactory.get("loadIntoProcessingTable")
                .tasklet(tasklet(sql))
                .build();       
    }


    public Tasklet tasklet(String sql) {
        return new TableOpsTasklet(sql, dataSource.getPrimaryDataSource());
    }

    @Bean
    public Step loadIntoProcessingTable() {
        return stepBuilderFactory.get("loadIntoProcessingTable")
                .<Project, Project> chunk(100)
                .reader(reader(dataSource.getSourceDataSource()))
                .processor(processor())
                .writer(jdbcWriter(dataSource.getPrimaryDataSource(), setter()))
                .build();
    }

    /*
    @Bean
    public JobRunScheduler scheduler() {
        JobRunScheduler scheduler = new JobRunScheduler();
        return scheduler;
    }
   */
    // end::jobstep[]
}

TableOpsTasklet.java

public class TableOpsTasklet implements Tasklet {


    private DataSource dataSource;

    private String sql;

    public TableOpsTasklet (String sql, DataSource dataSource) {
        this.sql = sql;
        this.dataSource = dataSource;
    }

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        System.out.println("Executing database operations");
         new JdbcTemplate(dataSource)
                .execute(sql);
         return RepeatStatus.FINISHED;
    }

}

Project.java

public class Project {

    private int id;
    private String name;
    private String description;
    private String creationDate;
    private String createdBy;

    public Project() {  

    }

    public Project(int id, String name, String description, String creationDate, String createdBy){
        this.id = id;
        this.name = name;
        this.description = description;
        this.creationDate = creationDate;
        this.createdBy = createdBy;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(String creationDate) {
        this.creationDate = creationDate;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    @Override
    public String toString() {
        return "Project [id=" + id + ", name=" + name + ", description=" + description + ", creationDate="
                + creationDate + ", createdBy=" + createdBy + "]";
    }


}

Application.java

@SpringBootApplication
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}
\$\endgroup\$
  • \$\begingroup\$ Hi, can you share some github url? \$\endgroup\$ – OEH Mar 10 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.