Spring Batch - Postgres Veritabanına Bağlanma Sorunları
Şimdiye kadar Spring Batch ile bellek içi H2 DB kullanıyordum. Ancak, şimdi harici postgres DB'ye bağlanmaya geçtim. İşte benim bağlantı nesnem (biraz şaşırtmalı):
@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;
}
Başvuruma başladığımda şunu alıyorum:
Nedeni: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; kötü SQL dilbilgisi [SELECT JOB_INSTANCE_ID, JOB_NAME, BATCH_JOB_INSTANCE'den JOB_NAME = nerede? ve JOB_KEY =?]; iç içe geçmiş istisna org.postgresql.util.PSQLException: HATA: "batch_job_instance" ilişkisi mevcut değil
Daha sonra Spring Batch'in veri tabanını kurtarma / yeniden deneme işlevi için meta verileri kaydetmek için kullandığını ve gömülü veri tabanlarında bunlar Spring Batch'in varsayılan olarak ayarladığı tablolar olduğunu okudum. Tamam, bu, bu hatayı neden daha önce hiç görmediğimi açıklar.
Ancak, bu özelliği ayarlayabileceğimi söyledi:
spring.batch.initialize-schema=never
Bu yüzden bunu application.properties dosyama koydum. Ancak yine de hatayı alıyorum. Herhangi bir fikir için minnettar olurum.
Yanıtlar
Bunu kendim çözebildim. Nihayetinde, gerçek hedef ilişkisel veritabanımdan bağımsız olarak Spring Batch deposuna ihtiyacım vardı. Bu yüzden bu referansı buldum:
https://github.com/spring-projects/spring-batch/blob/342d27bc1ed83312bdcd9c0cb30510f4c469e47d/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/DefaultBatchConfigurer.java#L84
Bu örnekten DefaultBatchConfigurer sınıfını alıp gömülü / yerel veri kaynağı için @Qualifier'ı ekleyerek veri kaynağında küçük bir değişiklik yapabildim:
@Autowired(required = false)
public void setDataSource(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
this.transactionManager = new DataSourceTransactionManager(dataSource);
}
Ardından, Spring Batch okuyucumda (diğer toplu yapılandırma sınıfımda), postgres veri kaynağı için @Qualifier ekleyerek veri kaynağında küçük bir değişiklik yaptım:
@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();
}
Sonra son olarak (veya öncelikle bunları ilk yaptığım gibi), veri kaynağı fasulye adımı açıkça adlandırdım, böylece java onları yukarıdaki gibi kullanmalarını söyleyebilsin:
@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; }
}
Yukarıdakilerin hepsini yaptıktan sonra, hata ortadan kalktı ve her şey işe yaradı.