嵌入式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
相关产品推荐
相关产品推荐

