Spring Batch - Problemas de conexão com o banco de dados Postgres
Até agora, eu estava usando o banco de dados H2 na memória com o Spring Batch. No entanto, agora mudei para conectar-me ao banco de dados postgres externo. Aqui estava meu objeto de conexão (com alguma ofuscação):
@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;
}
Quando inicio meu aplicativo, recebo:
Causado por: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; gramática SQL incorreta [SELECT JOB_INSTANCE_ID, JOB_NAME de BATCH_JOB_INSTANCE onde JOB_NAME = ? e JOB_KEY = ?]; exceção aninhada é org.postgresql.util.PSQLException: ERRO: a relação "batch_job_instance" não existe
Em seguida, li que o Spring Batch usa o banco de dados para salvar metadados para sua funcionalidade de recuperação/repetição e, com bancos de dados incorporados, essas são tabelas que o Spring Batch configura por padrão. Ok, isso explicaria porque eu nunca tinha visto esse erro antes.
No entanto, ele disse que eu poderia definir esta propriedade:
spring.batch.initialize-schema=never
Então eu coloquei isso no meu arquivo application.properties. No entanto, ainda estou recebendo o erro. Eu ficaria grato por todas as idéias.
Respostas
Eu fui capaz de resolver isso sozinho. Por fim, eu precisava do repositório Spring Batch independente do meu banco de dados relacional de destino real. Então encontrei esta referência:
https://github.com/spring-projects/spring-batch/blob/342d27bc1ed83312bdcd9c0cb30510f4c469e47d/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/DefaultBatchConfigurer.java#L84
Consegui pegar a classe DefaultBatchConfigurer desse exemplo e fazer uma pequena alteração na fonte de dados adicionando o @Qualifier para fonte de dados incorporada/local:
@Autowired(required = false)
public void setDataSource(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
this.transactionManager = new DataSourceTransactionManager(dataSource);
}
Em seguida, no meu leitor Spring Batch (em minha outra classe de configuração em lote), fiz uma pequena alteração na fonte de dados adicionando o @Qualifier para fonte de dados postgres:
@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();
}
Então, por último (ou primeiro, como fiz primeiro), nomeei explicitamente meus beans de fonte de dados para que o java pudesse diferenciá-los para usar como acima:
@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; }
}
Depois de fazer tudo o que foi dito acima, o erro desapareceu e tudo funcionou.