用于抑制 BatchDataInitializer 的 Spring-Boot 配置

Posted

技术标签:

【中文标题】用于抑制 BatchDataInitializer 的 Spring-Boot 配置【英文标题】:Spring-Boot Configuration for suppressing BatchDataInitializer 【发布时间】:2013-12-23 10:46:10 【问题描述】:

我将 Spring-boot 0.5.0.M6 与 Spring-Batch 一起使用。配置已通过使用 @EnableBatchProcessing 与 application.properties 中配置的数据源等。

在应用程序第一次运行期间,一切正常,但在我停止应用程序并重新启动应用程序后,出现以下错误

org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]; Duplicate entry '1' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:239)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:659)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:908)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:969)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:974)

在挖掘时,我在日志中观察到以下几行

2013-12-06 12:12:37 INFO  ResourceDatabasePopulator:162 - Executing SQL script from class path resource [org/springframework/batch/core/schema-mysql.sql]
2013-12-06 12:12:37 INFO  ResourceDatabasePopulator:217 - Done executing SQL script from class path resource [org/springframework/batch/core/schema-mysql.sql] in 13 ms.

这里的根本问题是 schema-drop-mysql.sql 不是由 schema-mysql.sql 触发的,因此在 BATCH_JOB_SEQ 中创建了两个条目。

为了解决同样的问题,我添加了

@EnableAutoConfiguration(exclude=BatchAutoConfiguration.class)

但是,由于这个原因,我需要显式执行 schema-mysql.sql,到目前为止还可以,但是当 spring-batch 版本使用模式中的更新进行更新时会出现问题

因此有几个问题: 1.如何在schema-mysql.sql之前自动配置批处理,甚至执行schema-drop-mysql.sql? 2. 有没有办法将此 BatchDatabaseInitializer 配置为运行一种“更新”模式?

问候

【问题讨论】:

不就是一个DEBUG日志吗?有害吗? 是的,戴夫,它是调试日志。但问题出在调试日志中,我看不到 schema-drop-mysql.sql 被执行。因此,这里发生的事情是 BATCH_STEP_EXECUTION_SEQ、BATCH_JOB_EXECUTION_SEQ 和 BATCH_JOB_SEQ 添加额外的值为 0 的行。然后 Spring Batch 尝试从 0 而不是更早的序列重新启动作业序列。这会导致 org.springframework.dao.DuplicateKeyException。 对,我明白了。迈克尔和我前段时间讨论过这个问题,他说他会修改架构。也许我们需要更新 Spring Batch 版本?或者,按照您的建议,添加一个删除选项。 github issue 是个讨论的好地方。 感谢戴夫和迈克尔。正如建议的那样,在 GitHub 问题 github.com/spring-projects/spring-boot/issues/149 中提出了同样的问题 【参考方案1】:

使用当前版本的 Spring Batch 自动配置(即将发布的版本无法实现),可以通过指定 spring.batch.initializer.enabled 属性并将其设置为 false 来禁用数据库表的自动创建。

恕我直言,您不应该使用自动创建/更新功能来创建架构,要么自己创建,要么使用 LiquiBase 或 FlyWay 等工具进行更可控的创建。

另见https://***.com/questions/8418814/db-migration-tool-liquibase-or-flyway

您始终可以自己执行schema-drop-mysql.sql,作为一种变通方法,您可以将@PreDestroy 方法添加到执行此脚本的@Configuration 类中。 (也许您甚至可以将其添加到仅在开发模式/配置文件中启用的 @Configuration 类中)。

【讨论】:

嗨。我同意将类似于 FlyWay 的工具用于自定义架构/实体。然而,这些表与 Spring 批处理框架集成在一起。因此,我想依赖 Spring Batch 框架中捆绑的 sql。这将简化迁移到春季批次的下一个版本。关于 preDestroy 方法,又是类似的问题。这些 SQL 捆绑在 JAR 中。因此,为了提供路径,需要详细说明spring批处理jar的显式版本。 我没有说过你不应该依赖提供的 sql。我只是说你不应该使用框架的自动创建功能!该 sql 位于(某种)众所周知的位置,因此您可以简单地访问它(使用 ClassPathResource )。此外,仅初始创建(目前)不支持迁移,迁移基本上意味着删除所有内容并重新创建。这也意味着您会丢失所有处决的历史记录。 用 github.com/spring-projects/spring-boot/issues/149 上的最新评论标记为已解决

以上是关于用于抑制 BatchDataInitializer 的 Spring-Boot 配置的主要内容,如果未能解决你的问题,请参考以下文章

使用 param 标签抑制空参数

非极大值抑制(NMS)

如何在 Jekyll 中抑制空白行?

java@SuppressWarnings

仅将熊猫值复制到字典:抑制索引 [重复]

.Net:如何抑制 TraceSource 标头(“SourceName TraceEventType:Id:”)?