Spring Batch-Postgres 데이터베이스 연결 문제
지금까지 Spring Batch와 함께 인 메모리 H2 DB를 사용하고있었습니다. 그러나 이제는 외부 postgres DB에 연결하는 것으로 전환했습니다. 내 연결 객체는 다음과 같습니다 (일부 난독 화 포함).
@Bean
public DataSource postgresDatasource() {
DriverManagerDataSource datasource = new DriverManagerDataSource();
datasource.setDriverClassName("org.postgresql.Driver");
datasource.setUrl("jdbc:postgresql://x.x.x.x:xxxx/blah");
datasource.setUsername("Joe");
datasource.setPassword("password");
return datasource;
}
신청을 시작하면 다음을 받게됩니다.
원인 : org.springframework.jdbc.BadSqlGrammarException : PreparedStatementCallback; 잘못된 SQL 문법 [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME =? 및 JOB_KEY =?]; 중첩 된 예외는 org.postgresql.util.PSQLException : 오류 : "batch_job_instance"관계가 없습니다.
그런 다음 Spring Batch가 데이터베이스를 사용하여 복구 / 재시도 기능을위한 메타 데이터를 저장하고 내장 된 데이터베이스를 사용하면 기본적으로 Spring Batch가 설정하는 테이블이라는 것을 읽었습니다. 좋아, 왜 내가 전에이 오류를 본 적이 없었는지 설명합니다.
그러나이 속성을 설정할 수 있다고 말했습니다.
spring.batch.initialize-schema=never
그래서 이것을 내 application.properties 파일에 넣었습니다. 그러나 여전히 오류가 발생합니다. 어떤 아이디어라도 감사하겠습니다.
답변
이 문제를 직접 해결할 수있었습니다. 궁극적으로 실제 대상 관계형 데이터베이스와는 독립적 인 Spring Batch 저장소가 필요했습니다. 그래서이 참조를 찾았습니다.
https://github.com/spring-projects/spring-batch/blob/342d27bc1ed83312bdcd9c0cb30510f4c469e47d/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/DefaultBatchConfigurer.java#L84
이 예제에서 DefaultBatchConfigurer 클래스를 가져와 임베디드 / 로컬 데이터 소스에 @Qualifier를 추가하여 데이터 소스를 약간 변경할 수있었습니다.
@Autowired(required = false)
public void setDataSource(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
this.transactionManager = new DataSourceTransactionManager(dataSource);
}
그런 다음 내 Spring Batch 리더 (다른 배치 구성 클래스)에서 postgres 데이터 소스에 대해 @Qualifier를 추가하여 데이터 소스를 약간 변경했습니다.
@Bean
public ItemReader<StuffDto> itemReader(@Qualifier("postgresDataSource")DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<StuffDto>()
.name("cursorItemReader")
.dataSource(dataSource)
.sql(GET_DATA)
.rowMapper(new BeanPropertyRowMapper<>(StuffDto.class))
.build();
}
그런 다음 마지막으로 (또는 처음에 실제로 처음으로 한 것처럼) 명시 적으로 데이터 소스 bean의 이름을 지정하여 Java가 위와 같이 사용하도록 구분할 수 있습니다.
@Configuration
public class PersistenceContext {
@Bean(name = "dataSource")
public DataSource dataSource() {
DriverManagerDataSource datasource = new DriverManagerDataSource();
datasource.setDriverClassName("org.h2.Driver");
datasource.setUrl("jdbc:h2:file:/tmp/test");
datasource.setUsername("sa");
datasource.setPassword("");
return datasource;
}
@Bean(name = "postgresDataSource")
public DataSource postgresDatasource() {
DriverManagerDataSource datasource = new DriverManagerDataSource();
datasource.setDriverClassName("org.postgresql.Driver");
datasource.setUrl("jdbc:postgresql://x.x.x.x:xxxx/blah");
datasource.setUsername("joe");
datasource.setPassword("password");
return datasource; }
}
위의 모든 작업을 수행하면 오류가 사라지고 모든 것이 작동했습니다.