如何配置spring批处理不自动创建用于存储元数据的批处理表?
Posted
技术标签:
【中文标题】如何配置spring批处理不自动创建用于存储元数据的批处理表?【英文标题】:How to configure spring batch not to auto create batch tables for storing meta data? 【发布时间】:2019-07-23 20:03:38 【问题描述】:我正在开发一个使用 JPA 对 PostGres 数据库执行 CRUD 操作的 spring 批处理。我正在使用 Spring Boot 2.1.3。即使我添加了以下配置以禁用 Spring 批处理以使用我的 postgres 数据库存储批处理作业元数据信息,我得到“错误:关系“batch_job_instance”不存在”异常,如下所示。我也遵循了here 中提到的解决方案。谁能建议需要做哪些额外的事情?
hibernate.temp.use_jdbc_metadata_defaults=false
spring.batch.initialize-schema=never
spring.batch.initializer.enabled=false
例外:
Exception in thread "main" 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
Position: 39
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:234)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1444)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:632)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:768)
at org.springframework.batch.core.repository.dao.JdbcJobInstanceDao.getJobInstance(JdbcJobInstanceDao.java:148)
at org.springframework.batch.core.repository.support.SimpleJobRepository.getLastJobExecution(SimpleJobRepository.java:297)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy69.getLastJobExecution(Unknown Source)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:101)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy78.run(Unknown Source)
at com.test.BatchApplication.main(BatchApplication.java:28)
Caused by: org.postgresql.util.PSQLException: ERROR: relation "batch_job_instance" does not exist
Position: 39
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2183)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:308)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:143)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:106)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:678)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
... 31 more
【问题讨论】:
【参考方案1】:由于您告诉 Spring Boot不要创建元数据表,因此您需要在数据源中预先手动创建它们。对于 Postgres,您需要在运行作业之前在数据库上执行 schema-postgresql.sql 脚本。
编辑:如果您不想保留元数据表,可以使用内存中基于 Map 的作业存储库:
@Configuration
@EnableBatchProcessing
public class MyJobConfiguration extends DefaultBatchConfigurer
@Override
protected JobRepository createJobRepository() throws Exception
MapJobRepositoryFactoryBean factoryBean = new MapJobRepositoryFactoryBean();
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
// other beans related to job definition
请注意,基于地图的作业存储库不适用于生产用途。
另一种选择是使用基于 JDBC 的作业存储库,但使用嵌入式数据库,如 HSQLDB、H2 等。
希望这会有所帮助。
【讨论】:
我根本不希望我的批处理作业实例创建元数据表。您能否建议我们是否可以通过任何配置更改来实现这一目标? 我在答案中添加了一个示例。希望对您有所帮助。 @MahmoudBenHassine - 虽然我的 pom.xml 文件中没有 H2 依赖项,但它仍然有效。你能解释一下这是如何工作的吗? 地图作业存储库不使用内存数据库(它使用地图存储元数据),这就是即使您的类路径中没有 h2 也可以工作的原因。我的回答中的第二个选项是使用基于 jdbc 的作业存储库,它需要一个数据库(无论是否是内存数据库)。希望这能澄清你的困惑。 @MahmoudBenHassine - 谢谢第一部分对我来说很干净。第二个选项部分仍然不清楚。请您再次澄清一下好吗?了解它是如何工作的很重要!任何链接也会有所帮助以上是关于如何配置spring批处理不自动创建用于存储元数据的批处理表?的主要内容,如果未能解决你的问题,请参考以下文章