SpringBatch-Postgresデータベースへの接続の問題
これまで、SpringBatchでインメモリH2DBを使用していました。しかし、今は外部のpostgresDBへの接続に切り替えました。これが私の接続オブジェクトでした(難読化されています):
@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文法[SELECTJOB_INSTANCE_ID、JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME =?およびJOB_KEY =?]; ネストされた例外はorg.postgresql.util.PSQLExceptionです:エラー:リレーション "batch_job_instance"は存在しません
次に、Spring Batchがデータベースを使用して、リカバリ/再試行機能のメタデータを保存していることを読みました。組み込みデータベースでは、これらはSpringBatchがデフォルトで設定するテーブルです。さて、それは私が以前にこのエラーを見たことがなかった理由を説明するでしょう。
ただし、このプロパティを設定できるとのことです。
spring.batch.initialize-schema=never
だから私はこれを私のapplication.propertiesファイルに入れました。ただし、まだエラーが発生します。どんなアイデアでもありがたいです。
回答
私はこれに自分で対処することができました。最終的には、実際のターゲットリレーショナルデータベースから独立したSpringBatchリポジトリが必要でした。だから私はこの参照を見つけました:
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; }
}
上記のすべてを実行すると、エラーは消え、すべてが機能しました。