Quarkus-JBeret集成下JdbcRepository添加JBeret表Schema的自定义属性/DDL问题咨询
解决 quarkiverse/quarkus-jberet 迁移至 JdbcRepository 后的 Schema 初始化问题
我之前也碰到过类似的情况,quarkus-jberet 确实没有直接暴露原生 JBeret 中通过 properties 定制 DDL 的能力,不过可以通过以下几种方式绕过这个限制:
1. 使用 Flyway 管理 JBeret 数据表 Schema
这是最推荐的方案,能和你的数据库迁移流程统一起来:
- 从 JBeret 官方资源中获取对应数据库的标准 DDL 脚本(比如 MySQL、PostgreSQL 等),或者直接复制下面的通用结构调整适配你的数据库:
CREATE TABLE JOB_INSTANCE ( JOB_INSTANCE_ID BIGINT NOT NULL PRIMARY KEY, VERSION BIGINT, JOB_NAME VARCHAR(100) NOT NULL, JOB_KEY VARCHAR(32) NOT NULL, constraint JOB_INSTANCE_UN unique (JOB_NAME, JOB_KEY) ); CREATE TABLE JOB_EXECUTION ( JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY, VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, CREATE_TIME TIMESTAMP NOT NULL, START_TIME TIMESTAMP DEFAULT NULL, END_TIME TIMESTAMP DEFAULT NULL, STATUS VARCHAR(10), EXIT_CODE VARCHAR(2500), EXIT_MESSAGE VARCHAR(2500), LAST_UPDATED TIMESTAMP, JOB_CONFIGURATION_LOCATION VARCHAR(2500), constraint JOB_INSTANCE_EXECUTION_FK foreign key (JOB_INSTANCE_ID) references JOB_INSTANCE(JOB_INSTANCE_ID) ); CREATE TABLE STEP_EXECUTION ( STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY, VERSION BIGINT NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, JOB_EXECUTION_ID BIGINT NOT NULL, START_TIME TIMESTAMP NOT NULL, END_TIME TIMESTAMP DEFAULT NULL, STATUS VARCHAR(10), COMMIT_COUNT BIGINT, READ_COUNT BIGINT, FILTER_COUNT BIGINT, WRITE_COUNT BIGINT, READ_SKIP_COUNT BIGINT, WRITE_SKIP_COUNT BIGINT, PROCESS_SKIP_COUNT BIGINT, ROLLBACK_COUNT BIGINT, EXIT_CODE VARCHAR(2500), EXIT_MESSAGE VARCHAR(2500), LAST_UPDATED TIMESTAMP, constraint JOB_EXECUTION_STEP_FK foreign key (JOB_EXECUTION_ID) references JOB_EXECUTION(JOB_EXECUTION_ID) ); CREATE TABLE STEP_EXECUTION_CONTEXT ( STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY, SHORT_CONTEXT VARCHAR(2500) NOT NULL, SERIALIZED_CONTEXT TEXT, constraint STEP_EXECUTION_CONTEXT_FK foreign key (STEP_EXECUTION_ID) references STEP_EXECUTION(STEP_EXECUTION_ID) ); CREATE TABLE JOB_EXECUTION_CONTEXT ( JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY, SHORT_CONTEXT VARCHAR(2500) NOT NULL, SERIALIZED_CONTEXT TEXT, constraint JOB_EXECUTION_CONTEXT_FK foreign key (JOB_EXECUTION_ID) references JOB_EXECUTION(JOB_EXECUTION_ID) ); - 将脚本命名为符合 Flyway 规范的格式(比如
V1__create_jberet_tables.sql),放到项目的src/main/resources/db/migration目录下。 - 确保项目已引入 Flyway 扩展:
<!-- pom.xml --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-flyway</artifactId> </dependency> - 启动应用时,Flyway 会自动执行这些脚本创建所需表结构。
2. 自定义启动事件执行 DDL 脚本
如果不需要完整的迁移管理,也可以通过 Quarkus 的启动事件手动执行 DDL:
- 创建一个观察者类,监听
StartupEvent:import io.quarkus.runtime.Startup; import io.quarkus.runtime.StartupEvent; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import javax.sql.DataSource; import java.sql.Connection; import java.sql.Statement; @ApplicationScoped @Startup public class JBeretSchemaInitializer { @Inject DataSource dataSource; public void onStartup(@Observes StartupEvent event) { try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) { // 这里放入你的JBeret DDL语句,或者读取外部脚本执行 String createTablesSql = """ CREATE TABLE IF NOT EXISTS JOB_INSTANCE ( JOB_INSTANCE_ID BIGINT NOT NULL PRIMARY KEY, VERSION BIGINT, JOB_NAME VARCHAR(100) NOT NULL, JOB_KEY VARCHAR(32) NOT NULL, constraint JOB_INSTANCE_UN unique (JOB_NAME, JOB_KEY) ); -- 其他表的DDL... """; stmt.execute(createTablesSql); } catch (Exception e) { throw new RuntimeException("Failed to initialize JBeret schema", e); } } } - 这种方式会在应用启动时自动执行DDL,注意加上
IF NOT EXISTS避免重复创建表的错误。
3. 尝试 quarkus-jberet 的隐藏配置项
虽然官方文档未明确说明,但可以尝试查看扩展源码,寻找未公开的配置项。比如有些扩展会支持类似 quarkus.jberet.jdbc.ddl-auto 的属性,你可以在 application.properties 中尝试添加:
quarkus.jberet.jdbc.ddl-auto=create
如果该属性生效,扩展会自动帮你创建所需的表结构。
以上几种方法都可以解决你遇到的Schema初始化问题,优先推荐第一种Flyway方案,因为它更符合现代应用的数据库迁移最佳实践。
内容的提问来源于stack exchange,提问作者Luca Basso Ricci
相关产品推荐
相关产品推荐

