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

嵌入式H2数据源无法获取表主键的问题求助

问题分析与解决方案

1. Schema名称大小写不匹配

在PostgreSQL兼容模式下,H2的默认Schema名称是大写的PUBLIC,但你调用getPrimaryKeys时传入的是小写的"public"。JDBC元数据查询对参数大小写敏感,这会导致无法匹配到目标Schema,进而找不到表的主键信息。

修复方式:

将getPrimaryKeys的schema参数改为null(让数据库自动使用当前默认Schema),或者改为大写的"PUBLIC":

// 方案1:使用null自动匹配默认Schema
try(ResultSet tableColumns = connection.getMetaData().getPrimaryKeys(null, null, table)) {

或:

// 方案2:传入大写的PUBLIC
try(ResultSet tableColumns = connection.getMetaData().getPrimaryKeys(null, "PUBLIC", table)) {

2. H2的PostgreSQL模式未正确启用

你通过setName("testDB;MODE=PostgreSQL")传递模式参数的方式不生效——setName仅负责设置数据库名称,后续的URL参数不会被正确解析,导致H2并未真正进入PostgreSQL兼容模式,元数据查询行为不符合预期。

修复方式:

使用addConnectionProperty单独配置PostgreSQL模式,还可添加大小写统一配置避免后续匹配问题:

@BeforeEach
void setUp() {
    dataSource = new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .setName("testDB")
            .addConnectionProperty("MODE", "PostgreSQL")
            .addConnectionProperty("DATABASE_TO_LOWER", "TRUE") // 可选:强制Schema和表名转为小写
            .addScript("schema.sql")
            .build();
    helper = new H(dataSource);
}

3. 表名大小写匹配验证(可选)

如果仍有问题,可以先打印数据库元数据中的表名和Schema,确认实际存储的名称:

@Test
void verifyTables() throws SQLException {
    try(Connection connection = dataSource.getConnection()) {
        DatabaseMetaData metaData = connection.getMetaData();
        try(ResultSet tables = metaData.getTables(null, null, "%", new String[]{"TABLE"})) {
            while(tables.next()) {
                System.out.println("表名:" + tables.getString("TABLE_NAME") + ",Schema:" + tables.getString("TABLE_SCHEM"));
            }
        }
    }
}

根据输出的实际名称调整pkKeys方法的参数即可。


内容的提问来源于stack exchange,提问作者SRJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:45:32