Spring 批处理 - 连接到 Postgres 数据库时出现问题
Spring Batch - Problems Connecting to Postgres Database
到目前为止,我一直在使用内存中的 H2 DB 和 Spring Batch。但是,现在我切换到连接到外部 postgres 数据库。这是我的连接对象(有些混淆):
@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;
}
当我启动我的应用程序时,我得到:
Caused by: org.springframework.jdbc.BadSqlGrammarException:
PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID,
JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?];
nested exception is org.postgresql.util.PSQLException: ERROR: relation
"batch_job_instance" does not exist
然后我读到 Spring Batch 使用数据库来保存其 recover/retry 功能的元数据,对于嵌入式数据库,这些表是 Spring Batch 默认设置的。好的,这就解释了为什么我以前从未见过这个错误。
然而,它说我可以设置这个属性:
spring.batch.initialize-schema=never
所以我把它放在我的 application.properties 文件中。但是,我仍然收到错误。如果有任何想法,我将不胜感激。
我自己解决了这个问题。最终,我需要独立于我的实际目标关系数据库的 Spring Batch 存储库。所以我找到了这个参考:
我能够从该示例中获取 DefaultBatchConfigurer class 并通过为 embedded/local 数据源添加 @Qualifier 对数据源进行较小的更改:
@Autowired(required = false)
public void setDataSource(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
this.transactionManager = new DataSourceTransactionManager(dataSource);
}
然后,在我的 Spring 批处理 reader 上(在我的其他批处理配置 class 中),我通过为 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; }
}
完成上述所有操作后,错误消失,一切正常。
到目前为止,我一直在使用内存中的 H2 DB 和 Spring Batch。但是,现在我切换到连接到外部 postgres 数据库。这是我的连接对象(有些混淆):
@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;
}
当我启动我的应用程序时,我得到:
Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]; nested exception is org.postgresql.util.PSQLException: ERROR: relation "batch_job_instance" does not exist
然后我读到 Spring Batch 使用数据库来保存其 recover/retry 功能的元数据,对于嵌入式数据库,这些表是 Spring Batch 默认设置的。好的,这就解释了为什么我以前从未见过这个错误。
然而,它说我可以设置这个属性:
spring.batch.initialize-schema=never
所以我把它放在我的 application.properties 文件中。但是,我仍然收到错误。如果有任何想法,我将不胜感激。
我自己解决了这个问题。最终,我需要独立于我的实际目标关系数据库的 Spring Batch 存储库。所以我找到了这个参考:
我能够从该示例中获取 DefaultBatchConfigurer class 并通过为 embedded/local 数据源添加 @Qualifier 对数据源进行较小的更改:
@Autowired(required = false)
public void setDataSource(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
this.transactionManager = new DataSourceTransactionManager(dataSource);
}
然后,在我的 Spring 批处理 reader 上(在我的其他批处理配置 class 中),我通过为 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; }
}
完成上述所有操作后,错误消失,一切正常。