Spring Batch
-
RowMapper<T>ってなに -
JPARepositoryからItemReader,ItemWriterを作れないのか -
[Spring Batch] ItemWriter内でJPARepositoryを使用してデータの更新を行う - Qiita
RepositoryItemReader/Writerを使うらしい
-
公式docs
-
Unittest
Job
- 複数の Step からなる
Step
Chunk
Job はチャンクタイプの Step からなり, チャンクタイプは
- 対象読み込み(
ItemReader<In>) - 処理(
ItemProcessor<In, Out>) - 書き込み(
ItemWriter<Out>)
の流れでバッチ処理が行われます.
各バッチは XXXBatchConfig で Job と Step が定義されています. これらのJobは XXXExecutor で @Scheduled がついたメソッドで定期実行されます.
@Component
class XXXExecutor(
private val jobLauncher: JobLauncher,
private val job: Job,
) {
@Scheduled(cron = "")
fun xxxBatch() { ... }
}
@Configuration
class XXXBatchConfig() {
@Bean
fun step(...): Step {
return stepBuilderFactory.get("step")
.chunk()
.reader(reader)
.processor(processor)
.writer(writer)
.build()
}
@Bean
fun job(step: Step): Job {
return jobBuilderFactory
.get("job")
.incrementer(RunIdIncrementer())
.start(step)
.build()
}
}Stepする
@Bean
public Step step1() {
return this.stepBuilderFactory.get("step1")
.<String, String>chunk(2)
.reader(fooReader())
.processor(fooProcessor())
.writer(compositeItemWriter())
.stream(barWriter())
.build();
}JPAPagingItemReader
@Bean
public JpaPagingItemReader itemReader() {
return new JpaPagingItemReaderBuilder<CustomerCredit>()
.name("creditReader")
.entityManagerFactory(entityManagerFactory())
.queryString("select c from CustomerCredit c")
.pageSize(1000)
.build();
}Tasklet
class HogeTasklet(
private val jobRepository: JobRepository
) : Tasklet {
override fun execute(contribution: StepContribution, context: ChunkContext): RepeatStatus {
return RepeatStatus.FINISHED
}
}TransactionManagerについて
メタテーブル
以下のメタテーブルが作成される
batch_job_instancebatch_job_executionbatch_job_execution_paramsbatch_job_execution_contextbatch_step_executionbatch_step_execution_context
@EnableBatchProcessing が DataSource を使う

-
spring 2.5.0+ では
spring.batch.jdbc.initialize-schema: alwaysでメタテーブル作成されるらしい
@ContextConfigurationConfigurationクラスでDIしている時はつけなければならない@SpringBatchtestは@SpringBootTestとどう違うのか
@SpringBatchTest
@RunWith(SpringRunner::class)
@ContextConfiguration(classes = [NotifyDealEndBatchConfiguration::class])
class BatchTest {
@Autowired
private lateinit var jobLauncherTestUtils: JobLauncherTestUtils
}
-
ItemReader,ItemWriterで使うServiceとかはConfigurationのコンストラクタでDIしては行けない, 各@Beanメソッドでparameter DIする -
どうやら
Configurationクラスの中で@ComponentをつけたクラスはDIしてくれない? -
Spring FrameworkとDIについて - mookjp.io
@SpringBootApplication=@Configuration+@EnableAutoConfiguration+@ComponentScan@ContextConfigurationのせい?- No qualifying bean of typeのエラー対処法 - Qiita
jobLauncherTestUtilsを使うのをやめてJobLauncherでjobを実行すればよかった
-
JobScope,StepScope: バッチ内のjob/scope毎にインスタンスを作るかどうか -
Rustなら,
mockall?- Rustの
derive trait全言語に欲しい - Rustでmockするならmockallで決まり!・・・でよろしいでしょうか? | 俺とお前とlaysakura
- Rustの
-
allowStartIfComplete(true)をつけないと毎回実行されない
Error creating bean with name ‘jobLauncherTestUtils’: Unsatisfied dependency expressed through method ‘setJob’ parameter 0; nested exception is org.springframework.beans.factory
が出る, 内部で @Autowire Job するがJobが複数あるから?
-> @SpringBatchTest をつけると内部で JobLauncherTestUtils
作ろうとするからつけずに @SpringBootTest だけつけて
jobLauncher.run(job, JobParameters()) で実行する
JobParameter
2023-01-22
同一 JobParameter での実行は同一ジョブの再起動と見做される
- そうしたくないなら
RunIdIncrementer()でjobidを変えるJobBuilder.preventRestart()を付ける(再起動不可能Jobとする)
- 渡す側
val now = Timestamp.valueOf(LocalDateTime.now()).time
val params = JobParametersBuilder()
.addLong("currentTime", now)
.toJobParameters()
jobLauncher.run(autoCompleteDealJob, params)- 受け取る側
@Value("#{jobParameters[xxx]}")Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'jobParameters' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
JobParametersを参照するBeanのスコープはStepスコープでなければならない
JobParametersを参照する際は、参照するBeanのスコープをStepスコープとする必要がある。 これは、JobParametersを参照する際に、Spring Batchのlate bindingという仕組みを使用しているためである。
- taskletなComponentを実装するのは
: Taskletでいいが, chunkの時はどうすれば?class: Taskletに@StepScope付けている例はたくさんあるが- 諦めて Tasklet で実装