我正在使用Spring批处理应用程序,该应用程序使用JPA Persistence写入数据库 . 我有一个场景,我必须在写入期间跳过异常,并且作业必须继续而不会失败 .

假设我有10条记录要写,而记录6会抛出一个SQL异常(表或视图不存在 . )我需要跳过这条记录并继续下一条记录 .

我尝试实现skippable-exception-classes但不能跳过异常并且作业失败 . 该作业抛出SQL异常 during persistence 操作(不在write()方法中抛出异常) .

'skippable-exception-classes'是否真的适用于JPA层中发生的任何异常?例如,如果在JPA提交期间发生了一些异常,是否真的可以使用'skippable-exception-classes'处理异常并阻止作业回滚所有提交到目前为止?请帮忙!

<batch:job id="advDataExtJob" job-repository="jobRepository"
    incrementer="myIncrementerImpl" restartable="false">
    <batch:step id="myStep">
        <batch:tasklet transaction-manager="transactionManager"             
            task-executor="taskExecutor"  allow-start-if-complete="true">
            <batch:chunk reader="myReader" processor="myProcessor"
                writer="MyWriter" commit-interval="1000" skip-limit="10">

                <batch:skip-policy>
                    <bean class="org.springframework.batch.core.step.skip.AlwaysSkipItemSkipPolicy" scope="step"/>
                </batch:skip-policy>

                <batch:skippable-exception-classes>
                    <batch:include class="java.lang.Throwable"/>
                </batch:skippable-exception-classes>
            </batch:chunk>
            <batch:listeners>
                <batch:listener ref="StepListener"/>
                <batch:listener ref="advExtStepListener"/>
                <batch:listener ref="ItemWriteListener"/>
                <batch:listener ref="ItemSkipListener"/>
            </batch:listeners>                  
        </batch:tasklet>
    </batch:step>
    <batch:validator ref="dataExtJobValidator"/>
    <batch:listeners>
                <batch:listener ref="dataExtJobListener"/>
                <batch:listener ref="advExtJobListener"/>
    </batch:listeners>
</batch:job>

跳过监听器如下

项目跳过监听器如下

@Override
    public void onSkipInRead(Throwable t) {
        System.out.println("skipped item: {} " + t.toString());
    }

    @Override
    public void onSkipInWrite(Object item, Throwable t) {
        // this.skipListener.onSkipInWrite(item, t);
        System.out.println("Here");

    }

    @Override
    public void onSkipInProcess(Object item, Throwable t) {
        // TODO Auto-generated method stub
        System.out.println("inside skip process item " + item.toString());
        System.out.println("error is " + t.getMessage());
    }

添加控制台错误日志

Exception [EclipseLink-4002] (Eclipse Persistence Services - 1.2.0.v20091016-r5565): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: ORA-01722: invalid number

Error Code: 1722
Call: INSERT INTO TEST_TABLE (SESSION_ID, LAST_NM, FAP_IND, TITLE, DOB, AGE, WM_ASGN_STATUS, GENDER, MID_NM, FIRST_NM, RES_STATE_CD) VALUES (?, ?, ?, ?, ?, ?, 

?, ?, ?, ?, ?)
    bind => [19081, MONROE, U, MS, 1948-12-04, age-is-given-as-String-instead-of-integer, F, JANE, TEST, OR]
Query: InsertObjectQuery(org.test.batch.model.data.MyDO@5ca178da)
Caused by: java.sql.SQLException: ORA-01722: invalid number
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
    2016-08-03 18:22:51,005 ERROR [taskExecutor-1] impl.MyDomain (MyDomain.java:203) - Exception [EclipseLink-4002] (Eclipse Persistence Services - 

1.2.0.v20091016-r5565): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: ORA-01722: invalid number