인프런 커뮤니티 질문&답변

seungwan37님의 프로필 이미지
seungwan37

작성한 질문수

스프링 배치

어플리케이션 예제 (2)

어플리케이션 예제(2) 엑셀파일이 안읽어와집니다ㅠ

작성

·

134

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>

 

image.png

 

잘 작성한거 같은데, 디버그 중단점 걸어놓아도 안걸러지네요ㅠㅠ 원인을 모르겠습니다..

requestDate 부분이랑 fileItemReader이 동작을 안하는거 같습니다.

 

 

 

답변 1

-2

안녕하세요, 인프런 AI 인턴입니다.

seungwan37님의 문제를 살펴보니, fileItemReader에서 requestDate를 정상적으로 받아 엑셀 파일을 읽는 과정에서 문제가 발생하는 것 같습니다. @Value("#{jobParameters['requestDate']}") String requestDate를 사용하여 jobParameters에서 requestDate를 받고 있으나, 해당 날짜에 맞는 엑셀 파일(product_20210101.csv)이 ClassPath에 존재하는지 확인이 필요합니다.

또한, IDE의 디버그 중단점이 걸리지 않는 문제는 fileItemReader에 대한 bean 생성 및 실행 과정에서 예상치 못한 오류 또는 requestDate 파라미터의 전달 문제로 인해 해당 코드 라인에 도달하지 못할 가능성이 있습니다.

  1. 다음의 확인 사항을 검토해보세요:

    • product_20210101.csv 파일이 프로젝트의 resources 폴더 안에 존재하는지 확인하세요. 파일 경로는 new ClassPathResource("product_" + requestDate +".csv")에 의해 결정됩니다.
    • requestDate=20210101이 정상적으로 Job Parameters로 전달되는지 확인하세요. IDE 내에서 설정한 --job.name=fileJob requestDate=20210101 설정이 정확히 적용되었는지 다시 한 번 체크해보세요.
    • 스프링 배치 Job 실행 로그 중 jobParameters가 정상적으로 출력되고 있는지 확인해보세요. 이를 통해 requestDate 파라미터가 정상적으로 전달되었는지도 확인할 수 있습니다.
  2. 배치 Job의 디버깅 포인트를 설정할 때는, 해당 Step이 실행되기까지 전체적인 Flow를 이해하는 것이 중요합니다. Job Execution 시작점부터 fileItemReader, fileItemProcessor, fileItemWriter까지 전체적인 실행 흐름에 따라 중단점을 걸어보며 단계별로 디버깅을 수행해보세요.

위 사항을 검토해도 문제가 해결되지 않는다면, 추가적으로 로그 출력 설정을 상세히 설정하여 해당 부분의 실행 과정을 로그를 통해 확인해보는 것도 좋은 방법입니다.

seungwan37님의 프로필 이미지
seungwan37
질문자

image.png

application.yml 파일과 동일한 경로에 엑셀파일도 존재하고,

 

SpringBatchApplication.main()에서 args파라미터 찍어보니

args[0] = --job.name=fileJob, args[1] = requestDate=20210101

잘 나옵니다..!

 

게다가 교수님의 깃허브 프로젝트를 클론받아서 해당 강의 부분까지 다른 파일 삭제해서 실행해도 동일한 문제가 발생합니다..!

 

seungwan37님의 프로필 이미지
seungwan37

작성한 질문수

질문하기