Spring批处理JdbcBatchItemWriter setSql从不引发异常

Spring批处理JdbcBatchItemWriter setSql从不引发异常,sql,spring,jakarta-ee,spring-batch,Sql,Spring,Jakarta Ee,Spring Batch,我的简单批处理流程从CSV文件中读取数据,然后写入MySQL数据库(批处理配置可以正常工作) 我正在使用JdbcBatchItemWriter的自定义实现来完成这项工作,实际上我正在我的writer构造函数中进行更新 CsvReader.java @Component @StepScope public class EducationCsvReader extends FlatFileItemReader { public final static String CSV_FILE

我的简单批处理流程从CSV文件中读取数据,然后写入MySQL数据库(批处理配置可以正常工作)

我正在使用JdbcBatchItemWriter的自定义实现来完成这项工作,实际上我正在我的writer构造函数中进行更新

CsvReader.java

@Component
@StepScope
public class EducationCsvReader extends FlatFileItemReader {    
    public final static String CSV_FILE_NAME = "education.csv.file";

    @Value("#{jobParameters['"+ CSV_FILE_NAME +"']}")
    public void setResource(final String csvFileName) throws Exception {
        setResource(
                new FileSystemResource(csvFileName)
        );

    }

    public EducationCsvReader() {
        setLinesToSkip(1);
        setEncoding("UTF-8");
        setStrict(true);
        setLineMapper((line, num) -> {
            String[] values = line.split(";");
            return new Education()
                    .setName(values[2].trim())
                    .setId(Integer.parseInt(values[0].trim()));
        });

    }

}
我的自定义JdbcBatchItemWriter:AbstractJdbcBatchItemWriter.java

public abstract class AbstractJdbcBatchItemWriter<T> extends JdbcBatchItemWriter<T>{

    @Autowired
    public AbstractJdbcBatchItemWriter(String SQL_QUERY) {
        setSql(SQL_QUERY);
    }

    @Autowired
    @Override
    public void setItemSqlParameterSourceProvider(
            @Qualifier("beanPropertyItemSqlParameterSourceProvider") ItemSqlParameterSourceProvider provider){
        super.setItemSqlParameterSourceProvider(provider);
    }

    @Autowired
    @Override
    public void setDataSource(@Qualifier("mysqlDataSource") DataSource dataSource){
        super.setDataSource(dataSource);
    }
}
公共抽象类AbstractJdbcBatchItemWriter扩展了JdbcBatchItemWriter{
@自动连线
公共抽象JDBCBatchItemWriter(字符串SQL\U查询){
setSql(SQL_查询);
}
@自动连线
@凌驾
public void setItemSqlParameterSourceProvider(
@限定符(“beanPropertyItemSqlParameterSourceProvider”)ItemSqlParameterSourceProvider(提供程序){
super.setItemSqlParameterSourceProvider(提供程序);
}
@自动连线
@凌驾
public void setDataSource(@Qualifier(“mysqlDataSource”)数据源数据源){
super.setDataSource(数据源);
}
}
下面是我的writer实现:MySQLWriter.java

@Component
public class EducationMysqlWriter extends AbstractJdbcBatchItemWriter<Education> {
    public EducationMysqlWriter(){
        super("");
        try {
            setSql("UPDATE ecole SET nom=:name WHERE id=:id");
        } catch (EmptyResultDataAccessException exception){
            setSql("INSERT INTO ecole (nom, id) VALUES (:name, :id");
        }
    }

}
@组件
公共类教育mysqlwriter扩展了AbstractJdbcBatchItemWriter{
公共教育mysqlwriter(){
超级(“”);
试一试{
setSql(“更新ecole SET nom=:name,其中id=:id”);
}捕获(EmptyResultDataAccessException异常){
setSql(“插入ecole(nom,id)值(:name,:id”);
}
}
}
我需要更新行,但如果它失败(EmptyResultDataAccessException),我需要执行插入。 但是EmptyResultDataAccessException显示在日志控制台上并终止作业,但是异常捕获永远无法进入MySQLWriter.java…

JdbcBatchItemWriter\setql
不会引发异常,因为它除了为实例变量分配字符串之外什么都不做。构造函数中的try块没有任何异常与write方法类似,它是在itemwriter第一次实例化时执行的,而write方法对正在处理的每个项目块执行一次。如果您读取stacktrace,我希望您会看到JdbcBatchtemWriter正在执行其write方法并引发异常

ItemWriter不会为每一行实例化,因此,假设您将有一些行需要插入,一些行需要更新,在构造函数中设置sql字符串似乎不是一个好主意

您可以重写ItemWriter#write方法,为插入使用单独的sql字符串,但使用以下命令使用一个字符串会更容易:


JdbcBatchItemWriter#setSql
不会引发异常,因为它除了为实例变量分配字符串之外什么都不做。是的,我知道,但我认为尝试通过write方法(在之后调用)更深入…引发异常的方法?重写write方法?
INSERT INTO ecol (nom, id) VALUES (:name, :id)
  ON DUPLICATE KEY UPDATE nom = :name;