묻고 답해요
150만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
순위 정보를
불러오고 있어요
-
미해결[스프링 배치 입문] 예제로 배우는 핵심 Spring Batch
@Configuration 어노테이션 관련 질문있습니다.
Spring에서 @Configuration은 Spring의 설정 파일에 사용 되는 용도로 알고 있습니다.따라서 Spring Project를 구성할 때 @Configuration이 붙은 파일은 Spring 설정 파일로 사용되고, 핵심 비지니스 로직은 @Service 등을 사용하여 구성하는 게 기본적인 것으로 알고 있는데 Batch에서는 @Configuration이 있는 Job class에서 reader, processor, writer 등의 핵심 비지니스 로직을 구성하는 이유가 있을까요? 예를 들면 accountRepository.save()를 실행하는 test라는 메소드를 Service.class에 선언하고 wirter에선 Service::test와 같이 호출할 수 있지 않나요?
-
미해결스프링 배치
예제 프로젝트 소스를 받고 싶습니다!!
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 실제로 현업에서 제가 배치를 처음부터 만질 기회가 생겨서 선생님의 프로젝트를 받아서 그걸 참고하면서 만들고 싶습니다.예제 프로젝트의 완성본 깃허브 링크를 받을 수 있을까요?
-
미해결스프링 배치
연속적이지 않은 Id의 Partitioner
안녕하세요.partitioner 강의를 듣다가 스프링 배치에서 제공하는 샘플 ColumnRangePartitioner을 확인했습니다.해당 파티셔너의 경우 연속적인 Id일 경우에는 파티션에 균등하게 분배를 할 수 있을텐데요. 중간에 삭제된 아이디가 있을 때는 어떻게 해야 균등하게 분배를 할 수 있을까요?[1, 2, 5, 7, 10, 11, 12, 13, 15, 17, 19, 20] ColumnRangePartitioner를 사용했을 때 파티션[1, 2, 5], [7, 10], [11, 12, 13, 15], [17, 19, 20] 균등하게 분배되는 파티션[1, 2, 5], [7, 10, 11], [12, 13, 15], [17, 19, 20] 아니면 ColumnRangePartitioner을 사용하고 어느정도 균등하게 분배되는거는 포기하고 사용해야할지 의견이 궁급합니다
-
해결됨스프링 배치
ItemReader에서 chunkSize의 두 사용 방법 비교
안녕하세요~ 강의 잘 들었습니다!다름이 아니라 ItemReader를 구현하는 과정에서 궁금한 게 생겨 질문드립니다.상황 1)chunkSize가 2000이면서 ItemReader에서는 1개의 row만 DB로부터 읽어 1개의 객체씩 반환하는 ItemReader상황 2)chunkSize가 1이면서 ItemReader에서는 2000개의 row를 DB로부터 읽어 2000개의 객체가 포함된 1개의 List 객체를 반환하는 ItemReader두 상황 다 DB커넥션은 1번만 맺고 쿼리를 실행할 것 같긴 한데DB 입장에서는 둘 중 어느 상황을 더 빨리 처리할지,또 코드 상으로는 둘 중 어느 방식으로 구현하는 게 유지보수나 외 측면에서 좋을지,또 어느 방식으로 ItemReader를 구현해야 성능 상 더 좋을지 궁금합니다!
-
미해결[스프링 배치 입문] 예제로 배우는 핵심 Spring Batch
다중 Job 구동시 질문 있습니다!!
안녕하세요. 강사님!다중 Job 구동 시에 질문이 있습니다.별도의 작업을 하는 Job을 생성하여 배치를 돌릴때, 각각의 Job을 테스트 하기 위해서는 파라미터로 Job Name을 넘겨주는 방법 밖에 없는 건가요?!
-
미해결스프링 배치
빈등록 관련 에러
***************************APPLICATION FAILED TO START***************************Description:Parameter 4 of constructor in io.springbatch.batch.job.api.SendJobConfiguration required a single bean, but 4 were found: - apiMasterStep: defined by method 'apiMasterStep' in class path resource [io/springbatch/batch/job/api/ApiStepConfiguration.class] - apiSlaveStep: defined by method 'apiSlaveStep' in class path resource [io/springbatch/batch/job/api/ApiStepConfiguration.class] - jobStep: defined by method 'jobStep' in class path resource [io/springbatch/batch/job/api/SendChildJobConfiguration.class] - fileStep: defined by method 'fileStep' in class path resource [io/springbatch/batch/job/file/FileJobConfiguration.class]Action:Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumedProcess finished with exit code 1이런 에러가 발생하는데 어케 해결해야 될까요? ㅠ
-
미해결스프링 배치
Partitioning 의 강의 중에 customer 입력 쿼리는 어디에 있나요?
partitioning 강의를 수강중인데요. Customer 데이터를 DB에 입력해야 테스트를 할 수 있을거 같은데요. 혹시 Customer 입력 쿼리는 어디에 있는지 알려주세요.
-
미해결스프링 배치
다수의 배치와 메타 테이블간 의존성 관련 질문드립니다
안녕하세요.실무에 Quartz + Batch를 조합한 스케줄링 적용을 위해 강의를 보며 고군분투 하는 와중에 질문이 있습니다.만약 배치 간격이 같다면 각각의 배치는 서로다른 비즈니스 로직을 수행하지만 배치 메타 데이터 저장을 위해 동시에 같은 메타 테이블에 접근을 해야되지 않나요 ?? 테스트를 해보니 중간에 batch_job_execution_context, batch_job_execution_param 같은 테이블에 insert 같은 작업을 하다 문제가 발생했다며 오류가 발생합니다. 어쩔수 없이 구조상 시간을 다르게 해야되는 건지 이미 수행중인 배치가 있는지 체크를 하고 작업을 잠시 미루도록 만들어야 하는지... 궁금합니다.(아직 학습이 미흡하여 부족한 질문.. 죄송합니다)
-
미해결스프링 배치
ItemStreamReader 중복실행관련 질문
저는 강의를 들으면서, 6번째에서 실패하면 6,7,8,9 이렇게 잡을 실행한다고 이해했는데 아래 코드와 같이 this.index == 7로 바꿨을때 6부터 시작하는게 아닌 5부터 시작하는데 의도한 설명이 맞을까요?? @Override public String read() { String item = null; if (this.index < this.items.size()) { System.out.println("read = " + index); item = this.items.get(index++); } if (this.index == 7 && !restart) { throw new RuntimeException("Restart is required!"); } return item; } // 1번째 실행 open update read = 0 read = 1 read = 2 read = 3 read = 4 update read = 5 read = 6 Exception : Restart is required! // 2번째 실행 open update read = 5 read = 6 read = 7 read = 8 read = 9 update update가장 최근에 실패한 지점부터 시작한다고 언급해주셨는데, 가장 최근에 실패한 Chunk부터 시작하는 것 같아서 원래 강사님께서 말씀하시려던 부분이 가장 최근에 실패한 Chunk부터 재실행 한다는게 맞을까요??맞다면, 중복실행이 될 수 있겠네요 read( ) 메서드에서는 ExecutionContext에 put을 하고 있는게 아니라서 클래스 내부변수 this.index가 변경되더라도 실제 DB에는 적용되지 않는 것 같네요.
-
미해결스프링 배치
스프링 배치 멀티서버 환경에 적용관련 질문
스프링 배치를 멀티서버에 적용할때 DB는 하나이고. 서버는 여러개 인데... 스프링 배치가 모든 서버에서 구동되는데 이 DB 에 많은 데이터 건수가 많을때. 각 서버에서 경쟁적으로 데이터를 처리해서 성능을 향상시키고 싶은데 혹시 방법이 있을까요?
-
미해결스프링 배치
rest api writer 관련 질문있습니다.
청크 프로세스에서 마지막에 Output의 값으로 A, B 2개의 Rest api를 호출해야 하는 경우입니다.A는 성공했으나 B에서 실패했다면 롤백 처리를 해야할텐데요..다만 디비가 아니라 스프링 배치가 기본적으로 지원해주는 롤백은 불가능 할거라 생각합니다.. 이런 경우 어떤 식으로 롤백을 처리하는게 좋은 방법인지 궁금합니다..Skip, Rertry, 실패로 인한 Job 종료에 따라 전부 다를거라 생각합니다.Skip : A 롤백 후 다음 청크 프로세스 실행Retry : A 롤백 후 다시 현재 청크 프로세스 실행실패로 인한 Job 종료 : A 롤백 후 종료 이 3가지의 케이스에 대해 어떻게 롤백 처리를 하는게 좋을 지 질문드립니다
-
미해결스프링 배치
예제소스가 전부 있는걸까요?
브런치가 몇개 중간에 비어있는거같은데 다른곳에서받는게있을까요?
-
미해결스프링 배치
커서와 페이징
안녕하세요. 수업 관련 질의드립니다. 커서와 페이징 처리방식 전제:커서 기반 리더는 SQL을 한번 실행해 해당 커넥션을 이용해 스트림 처리를 하고, 페이징 기반 리더는 청크 단위로 SQL을 여러번 실행해 데이터를 페이징 단위로 처리합니다.문제: 그러면 커서기반으로 처리되는 리더는 doRead() 를 호출할 때, 데이터를 하나가져오고, 매핑하고, 다시 iterate해서 데이터를 하나 가져오고 매핑하는 것인가요? 아니면 일단 청크사이즈만큼 가져오고 그 다음 iterate해서 매핑을 하는 것인가요?질문이유: 저는 전자를 커서방식 후자를 페이징 방식이라고 생각하였는데, 수업 시간에 커서도 데이터를 청크사이즈만큼 가져온다음 Iterate한다고 이해하여 제 인식에 잘못된 것이 있는지, 파악에 오류가 있는지 질의드립니다.감사합니다.
-
미해결스프링 배치
spring batch 5 버전 대응
spring batch 5 버전이 되면서 배치 설정과 관련해서 변화가 생긴 걸로 압니다.JobBuilderFactory와 StepBuilderFactory가 더 이상 사용되지 않고, @EnableBatchProcessing을 더 이상 권장하지 않고, DefaultBatchConfiguration 상속하여 job설정을 하는 등..기존 예제 소스를 spirng batch 5 버전에 맞게 refactoring하거나 아니면, 최소한 spring batch 5 버전에 맞는 설정 예시와 관련해서 추가로 문서를 정리해서 제공할 계획은 없나요?
-
미해결스프링 배치
reader 에서 반복 제어를 하고 싶은데 도움 부탁드립니다.
안녕하세요. 강의보면서 따라해보고 있는데 응용이 잘되지 않아 질문드립니다. JdbcPagingItemReader, ItemProcessor, JdbcBatchItemWriter 를 사용하여 스텝을 구성하고 여러 스텝으로 잡 하나를 만들어서 배치를 돌리려고 합니다.그런데 read 하는 테이블의 데이터가 실시간으로 계속 쌓인다면 read 가 끝나지 않으므로 배치가 멈추지 않고 계속 돌게 됩니다.read 할 데이터 개수가 고정일 때는 배치가 반복되는게 어차피 read 가 끝나면 멈춰서 문제가 안됐었는데, 실시간으로 쌓이는 상황을 생각하니 모니터링 등을 고민하다가 특정 시간대에 돌리고 멈췄다가 다시 돌리는 식으로 방향을 잡았습니다.그래서 repeatTemplate 를 사용해서 특정 개수만큼만 돌리고 잡을 완료시키고 싶습니다.그리고 나머지는 이후에 다른 잡에서 하려고 합니다. 보여주신 예제는 processor 에서 반복 제어를 하였는데 저는 read 에서 무한 반복을 막고 싶은 것이라서 reader 에 넣어봤습니다. 그런데 테스트해봤을 때 반복 제어가 되지 않고 데이터 있는 개수만큼 다 돌고 끝나게 됩니다. (현재 로컬 환경에서는 실시간으로 쌓이진 않지만 중간에 repeateTemplate 조건에 맞게 끊길 수 있는 개수로 테스트했습니다.)repeatTemplate 설정을 했는데 설정이 안먹고 제대로 설정도 안된 느낌입니다.. @Configuration 파일에서 일부 코드입니다.jdbcPagingItemReader() 에 코드를 추가했습니다. @Configuration @RequiredArgsConstructor public class ReportConfig { private final DataSource dataSource; private static final int CHUNK_SIZE = 2; /** * READ TARGET */ @Bean public JdbcPagingItemReader<RequestReportTargetDto> jdbcPagingItemReader() throws Exception { // 여기서부터 RepeatTemplate repeatTemplate = new RepeatTemplate(); repeatTemplate.setCompletionPolicy(new SimpleCompletionPolicy(3)); repeatTemplate.iterate(new RepeatCallback() { @Override public RepeatStatus doInIteration(RepeatContext context) throws Exception { System.out.println("ReportConfig.doInIteration"); return RepeatStatus.CONTINUABLE; } }); // 여기까지 추가했습니다. HashMap<String, Object> parameters = new HashMap<>(); parameters.put("reqReportYn", "N"); return new JdbcPagingItemReaderBuilder<RequestReportTargetDto>() .name("jdbcPagingItemReader") .dataSource(dataSource) .fetchSize(CHUNK_SIZE) .rowMapper(new BeanPropertyRowMapper<>(RequestReportTargetDto.class)) .pageSize(CHUNK_SIZE) .queryProvider(createQueryProvider()) .parameterValues(parameters) .build(); } @Bean public PagingQueryProvider createQueryProvider() throws Exception { SqlPagingQueryProviderFactoryBean qp = new SqlPagingQueryProviderFactoryBean(); qp.setDataSource(dataSource); qp.setSelectClause("M_ID, ...."); qp.setFromClause("from TARGET_TEST"); qp.setWhereClause("where REQ_REPORT_YN = :reqReportYn"); Map<String, Order> sortKeys = new HashMap<>(); sortKeys.put("M_ID", Order.ASCENDING); qp.setSortKeys(sortKeys); return qp.getObject(); } @Bean public Step step(JobRepository jobRepository, PlatformTransactionManager transactionManager, JdbcPagingItemReader<RequestReportTargetDto> reader) { return new StepBuilder("jdbcPagingStep", jobRepository) .<RequestReportTargetDto, List<RequestReportDto>> chunk(CHUNK_SIZE, transactionManager) .reader(reader) .processor(reportProcessor) .writer(jdbcBatchListItemWriter()) .transactionManager(transactionManager) .allowStartIfComplete(true) // 테스트 위해서 .build(); } @Bean public Step step2(JobRepository jobRepository, PlatformTransactionManager transactionManager, JdbcPagingItemReader<RequestReportTargetDto> reader) { return new StepBuilder("jdbcPagingStep2", jobRepository) .<RequestReportTargetDto, List<RequestReportDto>> chunk(CHUNK_SIZE, transactionManager) .reader(reader) .processor(orgReportProcessor) .writer(jdbcBatchListItemWriter2()) .transactionManager(transactionManager) .allowStartIfComplete(true)// 테스트 위해서 .build(); } @Bean public Job job(JobRepository jobRepository, Step step, Step step2) { return new JobBuilder("reportJob", jobRepository) .start(step) .next(step2) .build(); } } reader 를 설정파일 말고 따로 클래스로 빼서 ItemWriter implements 해서 구현체로 만들어야 하나 싶은데 그러면 JdbcPagingItemReader 를 쓰기가 어려워집니다. 검색 많이 해봤는데 생각보다 참고할 수 있는 자료가 적어서 응용이 어렵습니다ㅠ참고할만한 예제가 혹시 있을까요? 아니면 어떤 식으로 하면 좋을지 알려주시면 또 찾아보고 해보겠습니다.
-
해결됨[스프링 배치 입문] 예제로 배우는 핵심 Spring Batch
설정 관련 문의
안녕하세요 강사님 스프링 배치 입문 강의 잘 보고 있습니다.스프링 부트에서는 첨부해드린 사진과 같이 설정을 Gradle이 아닌 IntelliJ IDEA 로 바꾸면 실행 속도가 더 빠르다 해서이번 스프링 배치에서도 이와 같이 설정했더니 bean 관련 에러가 나면서 실행이 안되더라고요ㅠ빈 이름도 오타없이 정확하게 입력했기에 한참을 헤매다 해당 설정을 기존과 같이 Gradle로 바꿨더니 문제없이 실행이 되었습니다.혹시 해당 현상에 대해 이유를 알고 계시다면 알려주실 수 있나요??감사합니다!
-
해결됨스프링 배치
fileItemReader(null) 미호출 이슈
안녕하세요 강사님 강의 항상 잘듣고 있습니다.애플리케이션(2) 강의를 보며 실습하는데 아래 상황에서 진행이 되지 않아 질문 드립니다. 아래 이미지처럼 fileStep1() 메서드는 정상적으로 실행되었지만,fileItemReader(null) 메서드가 호출되지 않아서 그 후 진행을 못하고 있는 상황입니다. 브레이크 포인터로 따라가보니 reader가 제대로 넘어오지 않는 것 같습니다,상세한 내용은 아래와 같습니다. Method threw 'org.springframework.beans.factory.support.ScopeNotActiveException' exception. Cannot evaluate org.springframework.batch.item.file.FlatFileItemReader$$EnhancerBySpringCGLIB$$83a3aa5e.toString() 깃헙에 올려주신 Part11 branch 를 checkout 받아서 실행해보았지만 위와 동일한 증상이 있었습니다.혹시 원인이 무엇일까?좋은 강의 만들어주셔서 감사합니다.
-
해결됨[스프링 배치 입문] 예제로 배우는 핵심 Spring Batch
다중DB 접속 설정 에러
안녕하세요!강의 잘 봤습니다!강의 보고 다중DB를 설정하는과정에서 에러가나서 질문드려요여기서 하면 안되는거같은데 ... 도움부탁드릴려고 글 남깁니다!targetDb에서 select는 정상적으로 들어오는데 localDB save 할때 할당 문제인거 같은데 ...에로코드org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@4ff98dfc] for key [HikariDataSource (HikariPool-1)] bound to thread [scheduling-1] at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:467) ~[spring-orm-5.3.6.jar:5.3.6] at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400) ~[spring-tx-5.3.6.jar:5.3.6] at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) ~[spring-tx-5.3.6.jar:5.3.6] at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:595) ~[spring-tx-5.3.6.jar:5.3.6] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:382) ~[spring-tx-5.3.6.jar:5.3.6] ------ at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) [spring-context-5.3.6.jar:5.3.6] at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-5.3.6.jar:5.3.6] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_181] at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308) [na:1.8.0_181] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java) [na:1.8.0_181] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_181] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_181] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181] Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@4ff98dfc] for key [HikariDataSource (HikariPool-1)] bound to thread [scheduling-1] at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:193) ~[spring-tx-5.3.6.jar:5.3.6] at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:442) ~[spring-orm-5.3.6.jar:5.3.6] ... 93 common frames omitted 2024-02-26 12:16:27.150 INFO 23616 --- [ scheduling-1] o.s.batch.core.step.AbstractStep : Step: [step] executed in 737ms 2024-02-26 12:16:27.160 INFO 23616 --- [ scheduling-1] c.m.mj_agent.listener.JobLoggerListener : taragetJob Job is Done. (Status: FAILED) 2024-02-26 12:16:27.160 INFO 23616 --- [ scheduling-1] c.m.mj_agent.listener.JobLoggerListener : Job is Failed 2024-02-26 12:16:27.168 INFO 23616 --- [ scheduling-1] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=taragetJob]] completed with the following parameters: [{time=1708917386263}] and the following status: [FAILED] in 797ms localDbConfigpackage com.munjaon.mj_agent.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.util.HashMap; /** * */ @Configuration @PropertySource({ "classpath:application.yml" }) @EnableJpaRepositories( // basePackages = {"com.repia.collectweb.common", "com.repia.collectweb.schedule"}, // basePackages = {"com.munjaon.mj_agent.batch.local.repo"}, basePackages = {"com.munjaon.mj_agent.batch.local"}, entityManagerFactoryRef = "primaryEntityManager", transactionManagerRef = "primaryTransactionManager" ) public class LocalDbConfig { @Autowired private Environment env; @Bean @Primary @ConfigurationProperties(prefix = "spring.local-datasource.datasource.hikari") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @Primary public LocalContainerEntityManagerFactoryBean primaryEntityManager() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(primaryDataSource()); em.setPackagesToScan(new String[] { "com.munjaon.mj_agent.batch.local.repo.entity" }); HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); HashMap<String, Object> properties = new HashMap<>(); properties.put("hibernate.show_sql", env.getProperty("spring.jpa.show_sql")); properties.put("hibernate.format_sql", env.getProperty("spring.jpa.format_sql")); properties.put("hibernate.use_sql_comments", env.getProperty("spring.jpa.use_sql_comments")); properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.hbm2ddl.auto")); properties.put("hibernate.dialect", env.getProperty("spring.jpa.database-platform")); // properties.put("hibernate.dialect", env.getProperty("spring.jpa.database")); em.setJpaPropertyMap(properties); return em; } @Bean @Primary public PlatformTransactionManager primaryTransactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(primaryEntityManager().getObject()); return transactionManager; } }TargetDbConfigpackage com.munjaon.mj_agent.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; import java.util.HashMap; import java.util.Objects; /** * */ @Configuration @PropertySource({ "classpath:application.yml" }) @EnableTransactionManagement @EnableJpaRepositories( basePackages = {"com.munjaon.mj_agent.batch.target.repo"} , entityManagerFactoryRef = "targetDbEntityManager" , transactionManagerRef = "targetDbTransactionManager" ) public class TargetDbConfig { @Autowired private Environment env; @Bean // @Primary public LocalContainerEntityManagerFactoryBean targetDbEntityManager() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(targetDbDataSource()); em.setPackagesToScan(new String[] { "com.munjaon.mj_agent.batch.target.repo.entity" }); HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); HashMap<String, Object> properties = new HashMap<>(); properties.put("hibernate.show_sql", env.getProperty("spring.jpa.show_sql")); properties.put("hibernate.format_sql", env.getProperty("spring.jpa.format_sql")); properties.put("hibernate.use_sql_comments", env.getProperty("spring.jpa.use_sql_comments")); // properties.put("hibernate.hbm2ddl.auto", false); // properties.put("hibernate.dialect", false); properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.hbm2ddl.auto")); properties.put("hibernate.dialect", env.getProperty("spring.jpa.database-platform")); em.setJpaPropertyMap(properties); return em; } @Bean // @Primary @ConfigurationProperties(prefix = "spring.target-datasource.datasource.hikari") public DataSource targetDbDataSource() { return DataSourceBuilder.create().build(); } // @Primary // @Bean @Bean(name = "targetDbTransactionManager") public PlatformTransactionManager targetDbTransactionManager(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(Objects.requireNonNull(targetDbEntityManager().getObject())); } } 감사합니다!
-
해결됨스프링 배치
분류가 필요한 상황이 있는데 방향에 대해 질문드립니다.
안녕하세요.구현하고자 하는 배치를 해보면서 강의를 부분부분 병행하며 듣고 있는데, 제가 원하는 배치는 어떻게 설계 해야 하는지 고민이 되어 조언을 얻고 싶어 질문드립니다.구현하려는 상황은 다음과 같습니다. db 컬럼 중 플래그 값이 있고 그걸로 reader 에서 readread 한 데이터들로 processor 에서 로직 진행 (로직 중간중간 db 조회나 업데이트하는 상황도 생김) writer 에서 write 해야 하는 테이블이 4개 인데 processor 로직 조건에 따라 어떤 경우는 2개, 어떤 경우는 4개 등 write 되는 테이블 개수가 달라짐마지막에 최종적으로 read 한 모든 데이터의 플래그 값을 업데이트 쳐서 다음 read 에서 조회되지 않게 함 처음 생각은 reader 와 processor 를 하나씩 만들고 writer 를 여러개 만드려고 했습니다.processor 에서 리턴되는 객체 하나로 여러 테이블에 write 해도 될만큼 필드가 겹치는게 많아서 이렇게 생각했습니다.그래서 찾아보니 writer 에도 composite 과 classifierComposite 구현체가 있더라구요.그런데 둘 다 사용해봤는데 제가 원하는 바를 실현시키지 못했습니다. 분류 후 여러개를 writer 해야 하는데 composite 는 분류가 안되고 classifierComposite 은 하나만 writer 되더라구요.그래서 writer 여러개로 설계하는게 안맞는 방법인가 싶어서요.같은 맥락으로 processor 여러개로 하는 방법도 뭔가 그림이 잘 안그려지고..결국 step 을 여러개 하는 방향을 생각 중인데 이때도 고민거리가 생깁니다.step 으로 했을 때는 같은 조건으로 테이블 개수만큼 read 를 여러번 하게 된다는 단점이 있는 것 같아서요.그리고 4번에서 read 하는 조건 플래그 값을 update 하는데 첫번째 스탭에서 해버리면 다음 스탭에서 read 를 못하게 되버립니다.그리고 2번 과정도 각 테이블마다 거의 똑같고 마지막에 조건에 따라 저장할 테이블만 분류하는 과정만 있는건데 그거를 스탭마다 중복되게 하는 것도 그렇습니다. 구현 상황을 보셨을 때 어떤 식으로 처리하는게 좋다고 생각하시는지 궁금합니다.
-
해결됨스프링 배치
setSortKeys 로 정한 값에서 오류가 나는데 원인을 모르겠습니다.
@Bean public JdbcPagingItemReader<RequestReportTargetDto> jdbcPagingItemReader() throws Exception { HashMap<String, Object> parameters = new HashMap<>(); parameters.put("reqReportYn", "N"); return new JdbcPagingItemReaderBuilder<RequestReportTargetDto>() .name("jdbcPagingItemReader") .dataSource(dataSource) .fetchSize(10) .rowMapper(new BeanPropertyRowMapper<>(RequestReportTargetDto.class)) .pageSize(10) .queryProvider(createQueryProvider()) .parameterValues(parameters) .build(); } @Bean public PagingQueryProvider createQueryProvider() throws Exception { SqlPagingQueryProviderFactoryBean qp = new SqlPagingQueryProviderFactoryBean(); qp.setDataSource(dataSource); qp.setSelectClause("M_ID mId, SERVICE_NO serviceNo, SERVICE_TYPE serviceType, PRODUCT_CODE productCode, REQ_REPORT_YN reqReportYn"); qp.setFromClause("from TARGET_TEST"); qp.setWhereClause("where reqReportYn = :reqReportYn"); Map<String, Order> sortKeys = new HashMap<>(); sortKeys.put("mId", Order.ASCENDING); qp.setSortKeys(sortKeys); return qp.getObject(); }@Getter @Setter public class RequestReportTargetDto { private String mId; private String serviceNo; private String serviceType; private String productCode; private String reqReportYn; }위와 같이 하고 실행하면 아래 오류가 납니다. org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter '_mId': No value registered for key '_mId' at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:379) ~[spring-jdbc-6.1.2.jar:6.1.2] at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:472) ~[spring-jdbc-6.1.2.jar:6.1.2] at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:446) ~[spring-jdbc-6.1.2.jar:6.1.2]..... sort key 로 정해준 값에서 계속 오류가 나는데 원인을 못찾고 있습니다. sort key 를 바꾸면 바꾸는데로 앞에 _ 가 붙어서 위와 같은 오류가 납니다. 강사님이 디버깅할 때 찍어주신 것처럼 where 절에 sort key 가 추가가 되는데 거기서 오류가 나는 것 같습니다.수정해봐야 하거나 더 확인할 수 있는 부분이 있을까요??
주간 인기글
순위 정보를
불러오고 있어요