I am upgrading an app to newest Spring Boot 3, and because of that Spring Batch is upgraded to 5.2.3 (from 4.3.10).
The application did not persist batch states previously, it was using the "map based" job repository.
Since that map based repository completely removed in v5, I have to change to a JDBC table based repo. I have read the migration guide ( https://github.com/spring-projects/spring-batch/wiki/Spring-Batch-5.0-Migration-Guide ) and according to that I changed the following part of the application:
return new StepBuilder("cnyProcessStep", jobRepository) //
.allowStartIfComplete(true)//
.<ChangeDataHolder<CnyPushChangeData>, CnyPushAcknowledgementHolder> chunk(1)
.reader(cnyPushItemReader) //
.processor(compositeProcessor) //
.writer(cnyPushItemWriter) //
.faultTolerant()
.skipPolicy((t, skipCount) -> true) //
.listener(defaultBatchListener) //
.transactionAttribute(new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_NEVER))
.build();
to this:
...
@Autowired
private PlatformTransactionManager transactionManager;
...
return new StepBuilder("cnyProcessStep", jobRepository) //
.allowStartIfComplete(true)//
.<ChangeDataHolder<CnyPushChangeData>, CnyPushAcknowledgementHolder> chunk(1, transactionManager)
.reader(cnyPushItemReader) //
.processor(compositeProcessor) //
.writer(cnyPushItemWriter) //
.faultTolerant()
.skipPolicy((t, skipCount) -> true) //
.listener(defaultBatchListener) //
.transactionAttribute(new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_NEVER))
.build();
Basically I added the platform tx manager as a second parameter to the chunk(...) method.
I also created the required tables and sequences to the database schema ( schema-oracle.sql from the batch core artifact ).
After these changes, the job throws the following excpetion on execution:
...
Caused by: org.springframework.transaction.InvalidIsolationLevelException: DefaultJpaDialect does not support custom isolation levels due to limitations in standard JPA. Specific arrangements may be implemented in custom JpaDialect variants.
at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:64)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:421)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:532)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:405)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:639)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:374)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
at jdk.proxy2/jdk.proxy2.$Proxy375.getLastJobExecution(Unknown Source)
at org.springframework.batch.core.launch.support.TaskExecutorJobLauncher.run(TaskExecutorJobLauncher.java:109)
What's my mistake?