用于抑制 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 配置的主要内容,如果未能解决你的问题,请参考以下文章