⇧ Amazing...
Spring Batchでvalidationをどうする
CSVファイルなんかの外部ファイルを扱ってる場合、ファイルのフォーマットなんか崩れてる可能性もあると思うのですが、Spring Batchでvalidationをどうするか?
ちなみに、validationについては、
⇧ 上記サイト様が詳しいです。
Spring Batchでvalidationと言うと、
⇧ 上記サイト様によりますと、
- ValidatingItemProcessor
- BeanValidatingItemProcessor
のどっちかを使っていく感じになるらしい。
ただ、どうやら、値のvalidationのみで、ファイルのフォーマットのvalidationとかをしてくれるわけではないらしい。
ファイルのフォーマットのvalidationなんかは、
⇧ 各ライブラリで対応する感じになるんですかね?
Spring Batchでvalidationしてみる
Spring Batchでの入力の検証は、
- ValidatingItemProcessor
- BeanValidatingItemProcessor
のどっちかを使えと言うことらしいので、参考サイト様を写経して試してみようとしたのですが、BeanValidatingItemProcessorについては、ReaderとWriterのinputが同じデータ型でないと使えないっぽくて、
⇧ 公式のサンプルでも、ReaderとWriterで同じデータ型しか扱ってなかった。
BeanValidatingItemProcessorの定義を見てみたけど、
⇧ 型パラメーターが1つしか受け取れないことが関係してるんかね?
他の方法を調べた感じ、
⇧ 上記サイト様を参考に、
org.springframework.batch.item.validator.Validator#validate()
⇧ を使ってvalidationしていくしか無さそう。
ただ、上記のvalidatorがどういうわけか、Bean登録することができず...
ネットの情報だと、
springbatchbyexample.blogspot.com
⇧ org.springframework.batch.item.validator以外を使ってる情報が多かったので、org.springframework.batch.item.validator以外を使ってvalidationすることにしてみます。
利用するプロジェクトについては、新しく作成したのですが、
⇧ 概ね、上記の記事の時の内容です。
ファイルの構成は以下のような感じ。
まずは、足りない依存関係を追加で。
■/spring-batch-example/build.gradle
plugins { id 'java' id 'org.springframework.boot' version '2.7.5' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-batch' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' // https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter implementation group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter', version: '2.2.2' implementation 'com.opencsv:opencsv:5.7.1' implementation 'org.springframework.boot:spring-boot-starter-validation:2.7.5' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' runtimeOnly 'org.postgresql:postgresql' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.batch:spring-batch-test' } tasks.named('test') { useJUnitPlatform() }
設定など。
■/spring-batch-example/src/main/resources/application.properties
# データベース接続 spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost:5434/test spring.datasource.username=postgres spring.datasource.password=postgres # MyBatisでEntityクラスのフィールド名とデータベースのテーブルのカラム名の対応 mybatis.configuration.map-underscore-to-camel-case=true # バッチ処理が自動で実行されないように設定 spring.batch.job.enabled=false # ファイルアップロード spring.servlet.multipart.max-file-size=128KB spring.servlet.multipart.max-request-size=128KB spring.servlet.multipart.location=${java.io.tmpdir} # ログ logging.level.org.springframework.batch.core.step=debug logging.level.org.springframework.transaction=debug
で、バッチ処理でInputにあたるDTOクラスのフィールドにNotEmptyのvalidationを付与してみます。
■/spring-batch-example/src/main/java/com/spring/batch/example/demo/dto/CsvUser.java
package com.spring.batch.example.demo.dto; import javax.validation.constraints.NotEmpty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class CsvUser { @NotEmpty private String lastName; @NotEmpty private String firstName; @NotEmpty private String romeLastName; @NotEmpty private String romeFirstName; private String ohenroIds; }
そしたらば、プロセッサーでvalidation。
■/spring-batch-example/src/main/java/com/spring/batch/example/demo/batch/user/UserProcessor.java
package com.spring.batch.example.demo.batch.user; import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.validator.ValidationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.validation.BindingResult; import org.springframework.validation.DataBinder; import org.springframework.validation.ObjectError; import org.springframework.validation.Validator; import com.spring.batch.example.demo.dto.CsvUser; import com.spring.batch.example.demo.entity.ShikokuOhenroUser; import lombok.extern.log4j.Log4j2; @Component @Log4j2 public class UserProcessor implements ItemProcessor<CsvUser, ShikokuOhenroUser> { @Autowired Validator validator; @Override public ShikokuOhenroUser process(CsvUser item) throws Exception { // validation DataBinder binder = new DataBinder(item); binder.setValidator(validator); binder.validate(); BindingResult result = binder.getBindingResult(); if (result.hasErrors()) { StringBuilder sb = new StringBuilder(); for (ObjectError error: result.getAllErrors()) { sb.append(error.toString()) .append(System.getProperty("line.separator")); } log.error(sb.toString()); throw new ValidationException(sb.toString()); } // DTOからEntityへマッピング return ShikokuOhenroUser.builder() .firstName(item.getFirstName()) .lastName(item.getLastName()) .romeFirstName(item.getRomeFirstName()) .romeLastName(item.getRomeLastName()) .ohenroIds(item.getOhenroIds()) .build(); } }
ステップにプロセッサーを設定。
■/spring-batch-example/src/main/java/com/spring/batch/example/demo/batch/user/UserBatchConfig.java
package com.spring.batch.example.demo.batch.user; import java.nio.charset.StandardCharsets; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.batch.MyBatisBatchItemWriter; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepScope; import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.core.step.skip.AlwaysSkipItemSkipPolicy; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import com.spring.batch.example.demo.dto.CsvUser; import com.spring.batch.example.demo.entity.ShikokuOhenroUser; @Configuration @EnableBatchProcessing @ComponentScan("com.spring.batch.example.demo") public class UserBatchConfig { @Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Autowired private SqlSessionFactory sqlSessionFactory; @Autowired LocalValidatorFactoryBean localValidatorFactoryBean; @StepScope @Bean public FlatFileItemReader<CsvUser> flatFileItemReader(@Value("#{jobParameters['filePath']}") String filePath) { Resource fileResource = new FileSystemResource(filePath); // DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(); // lineTokenizer.setNames(new String[] {"lastName", "firstName", "romeLastName", "romeFirstName", "ohenroIds"}); // BeanWrapperFieldSetMapper<CsvUser> fieldSetMapper = new BeanWrapperFieldSetMapper<>(); // fieldSetMapper.setTargetType(CsvUser.class); // // DefaultLineMapper<CsvUser> lineMapper = new DefaultLineMapper<>(); // lineMapper.setLineTokenizer(lineTokenizer); // lineMapper.setFieldSetMapper(fieldSetMapper); // FlatFileItemReader<CsvUser> reader = new FlatFileItemReader<>(); // reader.setResource(fileResource); // reader.setLinesToSkip(1); // reader.setEncoding(StandardCharsets.UTF_8.name()); // reader.setLineMapper(lineMapper); // return reader; return new FlatFileItemReaderBuilder<CsvUser>() .name("flatFileItemReader") .resource(fileResource) .delimited() .names(new String[] {"lastName", "firstName", "romeLastName", "romeFirstName", "ohenroIds"}) .linesToSkip(1) .fieldSetMapper(new BeanWrapperFieldSetMapper<>() {{ setTargetType(CsvUser.class); }}) .encoding(StandardCharsets.UTF_8.name()) // .targetType(ShikokuOhenroUser.class) // .saveState(true) .build(); } @Bean public MyBatisBatchItemWriter<ShikokuOhenroUser> writer() { final MyBatisBatchItemWriter<ShikokuOhenroUser> writer = new MyBatisBatchItemWriter<>(); writer.setStatementId("com.spring.batch.example.demo.repository.ShikokuOhenroUserMapper.insert"); writer.setSqlSessionFactory(sqlSessionFactory); return writer; } @Bean public Job userJob(Step step2) { return jobBuilderFactory.get("validateUserJob") .incrementer(new RunIdIncrementer()) .start(step2) .build(); } // @Bean // public UserProcessor userProcessor() { // return new UserProcessor(); // } // @Bean // public BeanValidatingItemProcessor<?> beanValidatingItemProcessor() { // BeanValidatingItemProcessor<?> beanValidatingItemProcessor = new BeanValidatingItemProcessor<>(localValidatorFactoryBean); // beanValidatingItemProcessor.setFilter(true); // return beanValidatingItemProcessor; // } @Bean public Step step2(UserProcessor userProcessor) { return stepBuilderFactory.get("csvItemReaderStep") .<CsvUser, ShikokuOhenroUser> chunk(5) .reader(flatFileItemReader(null)) .processor(userProcessor) .writer(writer()) .faultTolerant() .skipPolicy(new AlwaysSkipItemSkipPolicy()) .build(); } }
で、インプットするCSVファイルで空の値を設定してみる。
で、実行してみると、
17:52:54.578 [Thread-0] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@36c045e9 . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.5) 2022-11-18 17:52:55.082 INFO 14420 --- [ restartedMain] c.s.b.e.d.SpringBatchExampleApplication : Starting SpringBatchExampleApplication using Java 11.0.14.1 on Toshinobu-PC with PID 14420 (C:\Eclipse-2022-03\workspace03\spring-batch-example\bin\main started by Toshinobu in C:\Eclipse-2022-03\workspace03\spring-batch-example) 2022-11-18 17:52:55.083 INFO 14420 --- [ restartedMain] c.s.b.e.d.SpringBatchExampleApplication : No active profile set, falling back to 1 default profile: "default" 2022-11-18 17:52:55.148 INFO 14420 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable 2022-11-18 17:52:55.148 INFO 14420 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG' 2022-11-18 17:52:56.793 INFO 14420 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2022-11-18 17:52:56.808 INFO 14420 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2022-11-18 17:52:56.808 INFO 14420 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.68] 2022-11-18 17:52:56.927 INFO 14420 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2022-11-18 17:52:56.928 INFO 14420 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1779 ms 2022-11-18 17:52:56.966 INFO 14420 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2022-11-18 17:52:57.285 INFO 14420 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2022-11-18 17:52:57.300 INFO 14420 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:postgresql://localhost:5434/test' 2022-11-18 17:52:58.114 INFO 14420 --- [ restartedMain] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: POSTGRES 2022-11-18 17:52:58.130 DEBUG 14420 --- [ restartedMain] .t.i.NameMatchTransactionAttributeSource : Adding transactional method [*] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT] 2022-11-18 17:52:58.131 DEBUG 14420 --- [ restartedMain] .t.i.NameMatchTransactionAttributeSource : Adding transactional method [create*] with attribute [PROPAGATION_REQUIRES_NEW,ISOLATION_SERIALIZABLE] 2022-11-18 17:52:58.131 DEBUG 14420 --- [ restartedMain] .t.i.NameMatchTransactionAttributeSource : Adding transactional method [getLastJobExecution*] with attribute [PROPAGATION_REQUIRES_NEW,ISOLATION_SERIALIZABLE] 2022-11-18 17:52:58.144 INFO 14420 --- [ restartedMain] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor. 2022-11-18 17:52:58.229 INFO 14420 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2022-11-18 17:52:58.570 INFO 14420 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2022-11-18 17:52:58.587 INFO 14420 --- [ restartedMain] c.s.b.e.d.SpringBatchExampleApplication : Started SpringBatchExampleApplication in 3.991 seconds (JVM running for 5.97) 2022-11-18 17:53:09.405 INFO 14420 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2022-11-18 17:53:09.406 INFO 14420 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2022-11-18 17:53:09.407 INFO 14420 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms 2022-11-18 17:53:16.124 INFO 14420 --- [nio-8080-exec-2] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=validateUserJob]] launched with the following parameters: [{filePath=C:\Users\TOSHIN~1\AppData\Local\Temp\insertUserdata.csv, time=1668761595919}] 2022-11-18 17:53:16.201 INFO 14420 --- [nio-8080-exec-2] o.s.batch.core.job.SimpleStepHandler : Executing step: [csvItemReaderStep] 2022-11-18 17:53:16.201 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.AbstractStep : Executing: id=279 2022-11-18 17:53:16.422 ERROR 14420 --- [nio-8080-exec-2] c.s.b.e.demo.batch.user.UserProcessor : Field error in object 'target' on field 'lastName': rejected value []; codes [NotEmpty.target.lastName,NotEmpty.lastName,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.lastName,lastName]; arguments []; default message [lastName]]; default message [空要素は許可されていません] 2022-11-18 17:53:16.423 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.tasklet.TaskletStep : Applying contribution: [StepContribution: read=5, written=0, filtered=0, readSkips=0, writeSkips=0, processSkips=0, exitStatus=EXECUTING] 2022-11-18 17:53:16.423 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.tasklet.TaskletStep : Rollback for RuntimeException: org.springframework.batch.item.validator.ValidationException: Field error in object 'target' on field 'lastName': rejected value []; codes [NotEmpty.target.lastName,NotEmpty.lastName,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.lastName,lastName]; arguments []; default message [lastName]]; default message [空要素は許可されていません] 2022-11-18 17:53:16.435 DEBUG 14420 --- [nio-8080-exec-2] o.s.t.support.TransactionTemplate : Initiating transaction rollback on application exception org.springframework.batch.item.validator.ValidationException: Field error in object 'target' on field 'lastName': rejected value []; codes [NotEmpty.target.lastName,NotEmpty.lastName,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.lastName,lastName]; arguments []; default message [lastName]]; default message [空要素は許可されていません] at com.spring.batch.example.demo.batch.user.UserProcessor.process(UserProcessor.java:38) ~[main/:na] at com.spring.batch.example.demo.batch.user.UserProcessor.process(UserProcessor.java:1) ~[main/:na] at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:134) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$1.doWithRetry(FaultTolerantChunkProcessor.java:239) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329) ~[spring-retry-1.3.4.jar:na] at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:255) ~[spring-retry-1.3.4.jar:na] at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:217) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.transform(FaultTolerantChunkProcessor.java:308) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:210) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:77) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.23.jar:5.3.23] at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:152) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:413) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:149) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-5.3.23.jar:5.3.23] at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) ~[spring-batch-core-4.3.7.jar:4.3.7] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.23.jar:5.3.23] at com.sun.proxy.$Proxy68.run(Unknown Source) ~[na:na] at com.spring.batch.example.demo.batch.user.UserJobLauncher.launchUserJob(UserJobLauncher.java:38) ~[main/:na] at com.spring.batch.example.demo.controller.rest.ShikokuOhenroController.userInsert(ShikokuOhenroController.java:37) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.23.jar:5.3.23] at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) ~[tomcat-embed-core-9.0.68.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.23.jar:5.3.23] at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) ~[tomcat-embed-core-9.0.68.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] 2022-11-18 17:53:16.437 DEBUG 14420 --- [nio-8080-exec-2] o.s.b.c.s.i.SimpleRetryExceptionHandler : Handled non-fatal exception org.springframework.batch.item.validator.ValidationException: Field error in object 'target' on field 'lastName': rejected value []; codes [NotEmpty.target.lastName,NotEmpty.lastName,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.lastName,lastName]; arguments []; default message [lastName]]; default message [空要素は許可されていません] at com.spring.batch.example.demo.batch.user.UserProcessor.process(UserProcessor.java:38) ~[main/:na] at com.spring.batch.example.demo.batch.user.UserProcessor.process(UserProcessor.java:1) ~[main/:na] at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:134) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$1.doWithRetry(FaultTolerantChunkProcessor.java:239) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329) ~[spring-retry-1.3.4.jar:na] at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:255) ~[spring-retry-1.3.4.jar:na] at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:217) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.transform(FaultTolerantChunkProcessor.java:308) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:210) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:77) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.23.jar:5.3.23] at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:152) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:413) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:149) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-5.3.23.jar:5.3.23] at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) ~[spring-batch-core-4.3.7.jar:4.3.7] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.23.jar:5.3.23] at com.sun.proxy.$Proxy68.run(Unknown Source) ~[na:na] at com.spring.batch.example.demo.batch.user.UserJobLauncher.launchUserJob(UserJobLauncher.java:38) ~[main/:na] at com.spring.batch.example.demo.controller.rest.ShikokuOhenroController.userInsert(ShikokuOhenroController.java:37) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.23.jar:5.3.23] at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) ~[tomcat-embed-core-9.0.68.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.23.jar:5.3.23] at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) ~[tomcat-embed-core-9.0.68.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] 2022-11-18 17:53:16.440 DEBUG 14420 --- [nio-8080-exec-2] o.s.b.c.s.i.FaultTolerantChunkProcessor : Skipping after failed process org.springframework.batch.item.validator.ValidationException: Field error in object 'target' on field 'lastName': rejected value []; codes [NotEmpty.target.lastName,NotEmpty.lastName,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.lastName,lastName]; arguments []; default message [lastName]]; default message [空要素は許可されていません] at com.spring.batch.example.demo.batch.user.UserProcessor.process(UserProcessor.java:38) ~[main/:na] at com.spring.batch.example.demo.batch.user.UserProcessor.process(UserProcessor.java:1) ~[main/:na] at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:134) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$1.doWithRetry(FaultTolerantChunkProcessor.java:239) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329) ~[spring-retry-1.3.4.jar:na] at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:255) ~[spring-retry-1.3.4.jar:na] at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:217) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.transform(FaultTolerantChunkProcessor.java:308) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:210) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:77) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.23.jar:5.3.23] at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:152) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:413) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:149) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-5.3.23.jar:5.3.23] at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) ~[spring-batch-core-4.3.7.jar:4.3.7] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128) ~[spring-batch-core-4.3.7.jar:4.3.7] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.23.jar:5.3.23] at com.sun.proxy.$Proxy68.run(Unknown Source) ~[na:na] at com.spring.batch.example.demo.batch.user.UserJobLauncher.launchUserJob(UserJobLauncher.java:38) ~[main/:na] at com.spring.batch.example.demo.controller.rest.ShikokuOhenroController.userInsert(ShikokuOhenroController.java:37) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.23.jar:5.3.23] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.23.jar:5.3.23] at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) ~[tomcat-embed-core-9.0.68.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.23.jar:5.3.23] at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) ~[tomcat-embed-core-9.0.68.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.23.jar:5.3.23] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.68.jar:9.0.68] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] 2022-11-18 17:53:16.443 DEBUG 14420 --- [nio-8080-exec-2] o.s.b.c.s.i.FaultTolerantChunkProcessor : Attempting to write: [items=[CsvUser(lastName=鈴木, firstName=二郎, romeLastName=suzuki, romeFirstName=jiro, ohenroIds=1,2,3,4,5,6), CsvUser(lastName=鈴木, firstName=三郎, romeLastName=suzuki, romeFirstName=saburo, ohenroIds=24,25,26,27,28), CsvUser(lastName=鈴木, firstName=五郎, romeLastName=suzuki, romeFirstName=goro, ohenroIds=81,82,83,84,85,86), CsvUser(lastName=鈴木, firstName=六郎, romeLastName=suzuki, romeFirstName=rokuro, ohenroIds=1,2,3,4,5,6)], skips=[[exception=org.springframework.batch.item.validator.ValidationException: Field error in object 'target' on field 'lastName': rejected value []; codes [NotEmpty.target.lastName,NotEmpty.lastName,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.lastName,lastName]; arguments []; default message [lastName]]; default message [空要素は許可されていません] , item=CsvUser(lastName=, firstName=四郎, romeLastName=suzuki, romeFirstName=shiro, ohenroIds=40,41,42,43,44,45,46)]]] 2022-11-18 17:53:16.468 DEBUG 14420 --- [nio-8080-exec-2] o.s.b.c.step.item.ChunkOrientedTasklet : Inputs not busy, ended: false 2022-11-18 17:53:16.468 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.tasklet.TaskletStep : Applying contribution: [StepContribution: read=0, written=4, filtered=0, readSkips=0, writeSkips=0, processSkips=1, exitStatus=EXECUTING] 2022-11-18 17:53:16.469 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.tasklet.TaskletStep : Saving step execution before commit: StepExecution: id=279, version=1, name=csvItemReaderStep, status=STARTED, exitStatus=EXECUTING, readCount=5, filterCount=0, writeCount=4 readSkipCount=0, writeSkipCount=0, processSkipCount=1, commitCount=1, rollbackCount=1, exitDescription= 2022-11-18 17:53:16.671 DEBUG 14420 --- [nio-8080-exec-2] o.s.b.c.s.i.FaultTolerantChunkProcessor : Attempting to write: [items=[CsvUser(lastName=鈴木, firstName=七郎, romeLastName=suzuki, romeFirstName=shichiro, ohenroIds=24,25,26,27,28,29), CsvUser(lastName=鈴木, firstName=八郎, romeLastName=suzuki, romeFirstName=hachiro, ohenroIds=40,41,42,43,44,45,46,47), CsvUser(lastName=鈴木, firstName=九郎, romeLastName=suzuki, romeFirstName=kyuro, ohenroIds=81,82,83,84,85,86), CsvUser(lastName=鈴木, firstName=十郎, romeLastName=suzuki, romeFirstName=jyuro, ohenroIds=1,2,3,4,5,6)], skips=[]] 2022-11-18 17:53:16.673 DEBUG 14420 --- [nio-8080-exec-2] o.s.b.c.step.item.ChunkOrientedTasklet : Inputs not busy, ended: true 2022-11-18 17:53:16.673 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.tasklet.TaskletStep : Applying contribution: [StepContribution: read=4, written=4, filtered=0, readSkips=0, writeSkips=0, processSkips=0, exitStatus=EXECUTING] 2022-11-18 17:53:16.674 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.tasklet.TaskletStep : Saving step execution before commit: StepExecution: id=279, version=2, name=csvItemReaderStep, status=STARTED, exitStatus=EXECUTING, readCount=9, filterCount=0, writeCount=8 readSkipCount=0, writeSkipCount=0, processSkipCount=1, commitCount=2, rollbackCount=1, exitDescription= 2022-11-18 17:53:16.676 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.AbstractStep : Step execution success: id=279 2022-11-18 17:53:16.678 INFO 14420 --- [nio-8080-exec-2] o.s.batch.core.step.AbstractStep : Step: [csvItemReaderStep] executed in 477ms 2022-11-18 17:53:16.680 DEBUG 14420 --- [nio-8080-exec-2] o.s.batch.core.step.AbstractStep : Step execution complete: StepExecution: id=279, version=4, name=csvItemReaderStep, status=COMPLETED, exitStatus=COMPLETED, readCount=9, filterCount=0, writeCount=8 readSkipCount=0, writeSkipCount=0, processSkipCount=1, commitCount=2, rollbackCount=1 2022-11-18 17:53:16.687 INFO 14420 --- [nio-8080-exec-2] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=validateUserJob]] completed with the following parameters: [{filePath=C:\Users\TOSHIN~1\AppData\Local\Temp\insertUserdata.csv, time=1668761595919}] and the following status: [COMPLETED] in 528ms
⇧ エラーが出るけど、バッチ処理自体は実行されて、CSVファイルで空の値を設定した行以外は登録されていることが確認できます。
というわけで、Spring Batchで用意されてるvalidationが微妙過ぎて使えないので、別の手段でvalidationするしかなかったという...
毎度モヤモヤ感が半端ない...
今回はこのへんで。