작성
·
54
0
package springbatch.batch.job.file;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
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.item.ItemProcessor;
import org.springframework.batch.item.database.JpaItemWriter;
import org.springframework.batch.item.database.builder.JpaItemWriterBuilder;
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.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import springbatch.batch.chunk.processor.FileItemProcessor;
import springbatch.batch.domain.Product;
import springbatch.batch.domain.ProductVO;
import javax.persistence.EntityManagerFactory;
@Configuration
@RequiredArgsConstructor
public class FileJobConfiguration {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private final EntityManagerFactory entityManagerFactory;
@Bean
public Job fileJob() {
return jobBuilderFactory.get("fileJob")
.start(fileStep1())
.build();
}
@Bean
public Step fileStep1() {
return stepBuilderFactory.get("fileStep1")
.<ProductVO, Product>chunk(10)
.reader(fileItemReader(null))
.processor(fileItemProcessor())
.writer(fileItemWriter())
.build();
}
@Bean
@StepScope
public FlatFileItemReader<ProductVO> fileItemReader(@Value("#{jobParameters['requestDate']}") String requestDate) {
return new FlatFileItemReaderBuilder<ProductVO>()
.name("flatFile")
.resource(new ClassPathResource("product_" + requestDate +".csv"))
.fieldSetMapper(new BeanWrapperFieldSetMapper<>())
.targetType(ProductVO.class)
.linesToSkip(1)
.delimited().delimiter(",")
.names("id","name","price","type")
.build();
}
@Bean
public ItemProcessor<ProductVO, Product> fileItemProcessor() {
return new FileItemProcessor();
}
@Bean
public JpaItemWriter<Product> fileItemWriter() {
return new JpaItemWriterBuilder<Product>()
.entityManagerFactory(entityManagerFactory)
.usePersist(true)
.build();
}
}
application.yml
spring:
profiles:
active: mysql
jpa:
hibernate:
ddl-auto: update
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
show-sql: true
open-in-view: false
properties:
hibernate.format_sql: true
---
spring:
config:
activate:
on-profile: mysql
datasource:
hikari:
jdbc-url: jdbc:mysql://localhost:3306/springbatch?useUnicode=true&character_set_server=utf8mb4
username: root
password: ----
driver-class-name: com.mysql.cj.jdbc.Driver
batch:
job:
names: ${job.name:NONE}
enabled: false
jdbc:
initialize-schema: always
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>spring-batch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-batch</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-batch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.0.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.20</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
잘 작성한거 같은데, 디버그 중단점 걸어놓아도 안걸러지네요ㅠㅠ 원인을 모르겠습니다..
requestDate 부분이랑 fileItemReader이 동작을 안하는거 같습니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
seungwan37님의 코드를 확인해보니, FlatFileItemReader
설정 과정에서 몇 가지 확인해야 할 사항이 있습니다.
ClassPathResource
위치 확인: new ClassPathResource("product_" + requestDate +".csv")
에서 지정된 CSV 파일이 정말로 클래스 패스(일반적으로는 resources
폴더 내)에 존재하는지 확인해주세요. 파일이 존재하지 않거나 경로가 잘못되었다면 FlatFileItemReader
는 파일을 찾을 수 없습니다.
requestDate
파라미터 전달 확인: 스프링 배치 잡을 실행할 때 --job.name=fileJob requestDate=20210101
와 같이 requestDate
가 올바르게 전달되고 있는지 확인해주세요. 잘못된 파라미터 전달 또는 파라미터가 전달되지 않는 경우 fileItemReader
에서 예상하는 파일 이름과 실제 파일 이름이 일치하지 않을 수 있습니다.
디버그 포인트 설정: FlatFileItemReader
뿐만 아니라 fileStep1()
메소드와 fileJob()
메소드에도 디버그 포인트를 설정하여 스프링 배치 잡이 예상대로 실행되는지 확인해보세요. 특히, 잡의 실행 흐름을 따르면서 각 구성 요소가 예상대로 동작하는지 점검하는 것이 중요합니다.
스프링 배치 로그 설정: 로그 레벨을 DEBUG로 설정하여 더 많은 정보를 얻을 수 있습니다. 이를 통해 FlatFileItemReader
의 동작 여부 및 FilePath
가 올바르게 생성되었는지 등 추가적인 정보를 얻을 수 있습니다.
위 사항들을 확인하시고도 문제가 해결되지 않는다면, 파일 읽기와 관련된 구체적인 에러 메시지나 로그를 확인해보는 것이 좋습니다. 에러 메시지는 종종 문제의 정확한 원인을 제공해 줄 수 있습니다.
도움이 되었길 바랍니다. 추가적인 질문이 있으시면 언제든지 문의하세요!