MyBatisPagingItemReader with ExecutorType.Batch
Issue
Cannot change the ExecutorType when there is an existing transaction in _____Processor.
1. Set a Consistent ExecutorType
Ensure that the ExecutorType is consistently set across all MyBatis operations. Typically, ExecutorType.BATCH is used for batch processing, but you can choose the appropriate one for your use case (SIMPLE, REUSE, BATCH).
In runtime, Spring Batch was excuted with ExecuteType.Batch, but annotation-base queries will be excuted with ExecuteType.SIMPLE, which is having differentition point.
1.1 Trouble Shooting and Solution
Implement MyBatisConfig with returning SqlSessionTemplate(sqlSessionFactory, ExecutorType.BATCH);
Let's show e.g
import org.apache.ibatis.session.ExecutorType;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@MapperScan("your.package.com.model.mapper")
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
// Ensure that the mapper XML files are found
factoryBean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:mappers/*.xml")
);
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory, ExecutorType.SIMPLE);
}
}
@MapperScan Annotation could be matched with interface of mapper location. if non-correct path was assigned, mapper interface do not find real object.
setMapperLocation method will be matched with mybatis.mapper-location in application.yml.
So, We need to match mapper-location path like classpath:*mappers/*.xml
Since I use absolute path in application.yml, which is unusuall case, classpath solution could not be fitted.
In theory, we would use classpath with ExecutorType.SIMPLE.
[Concenturate to understand issue environment]
MyBatisPageReaderBuilder will return ExecutorType.Batch, and this part causes Spring Batch ExecutorType not to be matched issue.
@Bean
@StepScope
public MyBatisCursorItemReader<______Dto__or__Entity> ___ItemReader(
@Value("#{jobParameters[UUID]}") String uuid) throws Exception {
Map<String, Object> parameterValues = new HashMap<>();
parameterValues.put("uuid", uuid);
MyBatisCursorItemReaderBuilder<YourDto> readerBuilder = new MyBatisCursorItemReaderBuilder<>();
readerBuilder.sqlSessionFactory(sqlSessionFactory);
readerBuilder.queryId("your.package.com.model.mapper.InterfaceMapper.select");
readerBuilder.parameterValues(parameterValues);
return readerBuilder.build();
}
Quote
org.springframework.dao.TransientDataAccessResourceException: Cannot change the ExecutorType when there is an existing transacti
Batch 프로젝트를 진행중에 아래와 같은 에러 발생하였습니다. Batch 삽질 삽질 삽질 에러 원인을 요약하자면 하나의 트랜잭션 안에서 다른 실행자를 사용할 수 없다라는 내용이다. 자세한 내용을
jessyt.tistory.com
https://bkjeon1614.github.io/blog/java-springbatch-7
Spring Batch 7편 - ItemReader - 아무거나 (github)
단, 본인 조회 프레임워크가 Querydsl, Jooq 라면 직접 구현해야할 수도 있다. 왜냐하면 왠만해선 JdbcItemReader 로 해결되지만, JPA 영속성 컨텍스트 지원이 안되서 HibernateItemReader 를 사용하여 Reader 구
bkjeon1614.github.io