You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:55:15