Spring Batch框架-自动创建批处理表

52

我使用Spring Batch框架创建了一个批处理作业,但我没有运行CREATE SQL的数据库权限。当我尝试运行批处理作业时,框架尝试创建TABLE_BATCH_INSTANCE时出现了错误。我试图禁用

<jdbc:initialize-database data-source="dataSource" enabled="false">    
 ...
</jdbc:initialize-database>

但是在我尝试后,仍然遇到了错误。

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 java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist

无论如何都可以禁用SQL,我只想测试我的读写器和处理器是否正常工作。

12个回答

69

1
刚刚升级到Spring Boot 2.5.3,在测试环境中使用H2数据库和Flyway时遇到了问题...手动创建BATCH表发生了两次...我不得不将initialize-schema设置为“never”...除了关键字似乎已经改变了:spring.batch.jdbc.initialize-schema=never - Dan
1
现在Spring Batch使用了这个属性:spring.batch.jdbc.initialize-schema=always - Prashant Singh
@PrashantSingh 你知道是从哪个版本开始的吗? - BitfulByte
1
不知道那个,但今天我在使用IntelliJ中的旧属性时发现spring.batch.initialize-schema=always已经被弃用了。所以在这里分享一下。 - Prashant Singh
1
感谢@PrashantSingh,我已经找到了源代码,并更新了答案,提供了额外的信息以警告未来的读者。 - BitfulByte
显示剩余2条评论

28

Spring Batch使用数据库来保存元数据以支持其恢复/重试功能。

如果您不能在数据库中创建表,则必须禁用此行为

如果您可以创建批处理元数据表但无法在运行时创建,则可能需要手动创建它们


使用MapJobRepositoryFactoryBean和ResourcelessTransactionManager禁用了SQL,谢谢。 - Einn Hann
Sergio,一个简单的问题,我可以删除/避免创建那些表吗?我只是使用Spring Batch从数据库中获取数据。 - Sushi
寿司,这是我列出的选项中第一个选项所做的事情(“如果您无法在数据库中创建表格,则...”) - Sergio

14

Spring Batch需要以下表来运行作业:

  • BATCH_JOB_EXECUTION
  • BATCH_JOB_EXECUTION_CONTEXT
  • BATCH_JOB_EXECUTION_PARAMS
  • BATCH_JOB_EXECUTION_SEQ
  • BATCH_JOB_INSTANCE
  • BATCH_JOB_SEQ
  • BATCH_STEP_EXECUTION
  • BATCH_STEP_EXECUTION_CONTEXT
  • BATCH_STEP_EXECUTION_SEQ

如果您使用h2数据库,则默认情况下它将创建所有必需的表:

  • spring.h2.console.enabled=true
  • spring.datasource.url=jdbc:h2:mem:testdb
  • spring.datasource.driverClassName=org.h2.Driver
  • spring.datasource.username=sa
  • spring.datasource.password=
  • spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

当您开始使用Mysql或任何其他数据库时,您需要将以下属性添加到application.properties中:

               spring.batch.initialize-schema=always

1
非常感谢!我遇到了下一个错误:JdbcSQLSyntaxErrorException: 找不到表“BATCH_STEP_EXECUTION_CONTEXT”。我通过这个方法解决了我的问题,现在我正在使用h2数据库。 - Yaroslav

10

自从Spring Boot 2.5.0起开始使用

# to always initialize the datasource:
spring.batch.jdbc.initialize-schema=always

# to only initialize an embedded datasource:
spring.batch.jdbc.initialize-schema=embedded

# to never initialize the datasource:
spring.batch.jdbc.initialize-schema=never

自2.5.0版本起,spring.batch.initialize-schema已被废弃,将在2.7.0版本中移除。


这对我有用。将spring.batch.initialize-schema=always替换为spring.batch.jdbc.initialize-schema=always。 - Lalit Mehra

8

我尝试使用postgreSQL来维护批处理模式。这对我有用。谢谢! - vijayakumarpsg587

2
似乎很傻,但有人可能会遇到同样的问题。
在删除数据库中所有表后,我尝试启动Spring Batch时收到了以下错误:
bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]
和:
Invalid object name 'BATCH_JOB_INSTANCE'
这是因为我在没有重新启动服务的情况下删除了这些表。服务已经启动并接收到带有批处理表的数据库元数据。在删除它们并且不重新启动服务器之后,Spring Batch认为这些表仍然存在。
重新启动Spring Batch服务器并再次执行批处理后,表格将被创建而无需出现错误。

2

当使用Spring Boot时:

使用Spring Boot v1.5.14.RELEASE,Spring v4.3.18.RELEASE运行

这应该就足够了:

spring:
    batch:
        initializer:
            enabled: false

在这个Spring Boot版本中,initialize-schema无法正常工作。 之后,我能够从spring-core jar中复制SQL脚本,并更改表的大写形式,因为这是在Windows/Mac/Linux下自动创建表时出现的问题。


1
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/jdbc 
        http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">


    <!-- database -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/springbatch" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

    <!-- transaction manager -->
    <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

    <!-- create job-meta tables automatically -->
    <jdbc:initialize-database data-source="dataSource">
        <jdbc:script location="org/springframework/batch/core/schema-drop-mysql.sql" />
        <jdbc:script location="org/springframework/batch/core/schema-mysql.sql" />
    </jdbc:initialize-database>
</beans>

请确保您正在使用与 spring-batch 兼容的 spring-jdbc 版本。最有可能兼容的版本是 spring-jdbc-3.2.2.RELEASE.JAR

0

<jdbc:initialize-database/> 标签由 Spring 使用 InitializeDatabaseBeanDefinitionParser 进行解析。您可以在 IDE 中尝试调试此类,以确保 enabled 属性选择了哪些值。此外,可以使用 JVM 参数 -Dspring.batch.initializer.enabled=false 来禁用此值。


对于CREATE SQL,它没有显示错误,所以我假设它被禁用了。只是当我重新运行批处理作业时,它再次提示我SQL错误,但这次与SELECT SQL相关。 - Einn Hann
尝试使用Spring Batch数据源配置中使用的凭据从数据库客户端运行“SELECT JOB_INSTANCE_ID,JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = xxx and JOB_KEY =xxx”,并查看是否存在任何访问问题。 - Shailendra

0
请使用以下设置,因为建议的设置已被弃用:

spring.batch.jdbc.initialize-schema=always


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接