Spring Batch - Problemi di connessione al database Postgres
Fino ad ora avevo utilizzato H2 DB in memoria con Spring Batch. Tuttavia, ora sono passato alla connessione al DB postgres esterno. Ecco il mio oggetto di connessione (con qualche offuscamento):
@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 avvio la mia applicazione, ottengo:
Causato da: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; grammatica SQL errata [SELECT JOB_INSTANCE_ID, JOB_NAME da BATCH_JOB_INSTANCE dove JOB_NAME = ? e JOB_KEY = ?]; l'eccezione nidificata è org.postgresql.util.PSQLException: ERRORE: la relazione "batch_job_instance" non esiste
Ho quindi letto che Spring Batch utilizza il database per salvare i metadati per la sua funzionalità di recupero/riprova e, con i database incorporati, queste sono le tabelle che Spring Batch imposta per impostazione predefinita. Ok, questo spiegherebbe perché non avevo mai visto questo errore prima.
Tuttavia, ha detto che potevo impostare questa proprietà:
spring.batch.initialize-schema=never
Quindi l'ho inserito nel mio file application.properties. Tuttavia, sto ancora ricevendo l'errore. Sarei grato per qualsiasi idea.
Risposte
Sono stato in grado di affrontarlo da solo. Alla fine avevo bisogno del repository Spring Batch indipendente dal mio attuale database relazionale di destinazione. Allora ho trovato questo riferimento:
https://github.com/spring-projects/spring-batch/blob/342d27bc1ed83312bdcd9c0cb30510f4c469e47d/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/DefaultBatchConfigurer.java#L84
Sono stato in grado di prendere la classe DefaultBatchConfigurer da quell'esempio e apportare una piccola modifica all'origine dati aggiungendo @Qualifier per l'origine dati incorporata/locale:
@Autowired(required = false)
public void setDataSource(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
this.transactionManager = new DataSourceTransactionManager(dataSource);
}
Quindi, sul mio lettore Spring Batch (nell'altra mia classe di configurazione batch), ho apportato una piccola modifica all'origine dati aggiungendo @Qualifier per l'origine dati 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();
}
Quindi, infine (o in primo luogo proprio come ho fatto prima), ho chiamato esplicitamente i miei bean di origine dati in modo che Java potesse distinguerli per usarli come sopra:
@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; }
}
Dopo aver fatto tutto quanto sopra, l'errore è scomparso e tutto ha funzionato.