Spring引导批处理中的StoredProcedureItemReader

时间:2018-05-11 21:41:16

标签: java spring-boot db2 spring-batch batch-processing

我尝试使用 StoredProcedureItemReader 为游标批量读取DB2存储过程。 sql字符串没有被执行,默认的sql被传递给jdbctemplate

    public class MyItemPreparedStatementSetter implements PreparedStatementSetter {

    @Override
    public void setValues(PreparedStatement ps) throws SQLException {

        ps.setString(1, "UH");
        ((CallableStatement) ps).registerOutParameter(2, Types.VARCHAR);
        ((CallableStatement) ps).registerOutParameter(3, Types.CHAR);
        ((CallableStatement) ps).registerOutParameter(4, Types.INTEGER);
    }

}
   @Bean
public StoredProcedureItemReader<PrintResponse> jdbcReader(JdbcTemplate jdbcTemplate) throws Exception {
    StoredProcedureItemReader<PrintResponse> storedProcedureItemReader = new StoredProcedureItemReader<>();
    SqlParameter[] parameters = {new SqlParameter("@I_PRODUCT_CDE", Types.CHAR)
            , new SqlParameter("@O_ERROR_MESSAGE", Types.VARCHAR), new SqlParameter("@O_SQLSTATE", Types.CHAR)
            ,new SqlParameter("@O_SQLCODE", Types.INTEGER)};

    storedProcedureItemReader.setFunction(true);        
    storedProcedureItemReader.setDataSource(jdbcTemplate.getDataSource());
    storedProcedureItemReader.setProcedureName("DEVTEST.PP_GETALLPRINTREADY");        
    storedProcedureItemReader.setRowMapper(new PolicyPrintResultRowMapper());
    storedProcedureItemReader.setParameters(parameters);
    storedProcedureItemReader.setPreparedStatementSetter(new MyItemPreparedStatementSetter());

    storedProcedureItemReader.setCurrentItemCount(0);

    storedProcedureItemReader.afterPropertiesSet();
    System.out.println(storedProcedureItemReader.getSql());

    return storedProcedureItemReader;       
}

我正在使用Job调用的Batch步骤:

@Autowired
public JobBuilderFactory jobBuilderFactory;

@Autowired
public StepBuilderFactory stepBuilderFactory;

@Autowired
@Qualifier("jdbcTemplate")
JdbcTemplate jdbcTemplate; 

    @Bean
public ItemWriter<PrintResponse> fileWriter(@Value("${output}") Resource resource) {

    LineAggregator<PrintResponse> lineAggregator = new DelimitedLineAggregator<>();
    return new FlatFileItemWriterBuilder<PolicyPrint>()
            .name("file-writer")
            .resource(resource) 
            .lineAggregator(lineAggregator)
            .build();
}

@Bean
public Job jobPrintRecord(JobBuilderFactory jobBuilderFactory, Step step1) {
    return jobBuilderFactory.get("jobPrintAll")
            .incrementer(new RunIdIncrementer())
            .start(step1)
            .build();
 }

@Bean
public Step step1() throws Exception {
    return stepBuilderFactory.get("step1")
            .<PrintResponse, PrintResponse>chunk(5)
            .reader(jdbcReader(jdbcTemplate))
            .writer(fileWriter(null))
            .build();
}

以下是传递的默认查询:

错误的SQL语法[SELECT JOB_INSTANCE_ID,来自BATCH_JOB_INSTANCE的JOB_NAME = JOB_NAME =?按JOB_INSTANCE_ID desc]排序;

错误堆栈如下:

 java.lang.IllegalStateException: Failed to execute CommandLineRunner org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:797) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]   ... 5 common frames omitted

引起:com.ibm.db2.jcc.am.SqlSyntaxErrorException:DB2 SQL错误:SQLCODE = -204,SQLSTATE = 42704,SQLERRMC = TEIWUDB1.BATCH_JOB_INSTANCE,DRIVER = 4.21.29 at com.ibm.db2.jcc.am.kd.a(kd.java:810)〜[db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2.jcc.am.kd.a(kd .java:66)〜[db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2.jcc.am.kd.a(kd.java:140)~ [db2jcc4-11.1-4.21.29。 jar:na] at com.ibm.db2.jcc.am.sp.c(sp.java:2796)~ [db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2.jcc.am. sp.d(sp.java:2784)〜[db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2.jcc.am.sp.a(sp.java:2212)~ [db2jcc4-11.1 -4.21.29.jar:na] at com.ibm.db2.jcc.am.tp.a(tp.java:7997)~ [db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2 .jcc.t4.bb.i(bb.java:148)〜[db2jcc4-11.1-4.21.29.jar:NA]在com.ibm.db2.jcc.t4.bb.b(bb.java:41) 〜[db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2.jcc.t4.pa(p.java:32)〜[db2jcc4-11.1-4.21.29.jar:na] at com。 ibm.db2.jcc.t4.vb.i(vb.java:145)〜[db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2.j cc.am.sp.kb(sp.java:2181)〜[db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2.jcc.am.tp.yc(tp.java:3698)〜 [db2jcc4-11.1-4.21.29.jar:NA]在com.ibm.db2.jcc.am.tp.a(tp.java:4578)〜[db2jcc4-11.1-4.21.29.jar:NA]在玉米.ibm.db2.jcc.am.tp.b(tp.java:4173)〜[db2jcc4-11.1-4.21.29.jar:NA]在com.ibm.db2.jcc.am.tp.lc(TP。 java:770)〜[db2jcc4-11.1-4.21.29.jar:na] at com.ibm.db2.jcc.am.tp.executeQuery(tp.java:735)~ [db2jcc4-11.1-4.21.29.jar :na] at org.springframework.jdbc.core.JdbcTemplate $ 1.doInPreparedStatement(JdbcTemplate.java:666)〜[spring-jdbc-5.0.5.RELEASE.jar:5.0.5.RELEASE] org.springframework.jdbc。 core.JdbcTemplate.execute(JdbcTemplate.java:605)〜[spring-jdbc-5.0.5.RELEASE.jar:5.0.5.RELEASE] ...省略了27个常用框架

为什么我没有获得结果集或能够执行查询。我是春季批次的新手,有点卡住了。调试显示,数据源配置正确。

谢谢!

1 个答案:

答案 0 :(得分:0)

问题已解决,我使用了Map的默认内存使用而不是物理数据库。任何遇到相同问题的人都会覆盖setDatasource并将其留空,如下所示:

    public class BatchConfiguration extends DefaultBatchConfigurer
 { 
@Override public void setDataSource(DataSource dataSource) {
 // override to do not set datasource even if a datasource exist. 
// initialize will use a Map based JobRepository (instead of database) 
} 
}