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

Spring应用中阻止H2将标识符转为大写的问题求助

H2数据库与Liquibase多Schema迁移大小写问题

环境与问题描述

  • Spring版本:2.6.2
  • 测试使用H2版本:2.1.214、1.4.200
  • 操作流程:应用启动时通过JDBC执行原生SQL创建Schema,随后由Liquibase执行数据库迁移
  • 正常表现:PostgreSQL环境下,Schema按指定字符串字面量创建,Schema内表名保持Liquibase变更日志定义的小写
  • 异常表现:H2单元测试中,针对002schema执行迁移时抛出异常,Liquibase试图访问大写的002SCHEMA,但该Schema不存在

创建Schema的原生SQL

CREATE SCHEMA IF NOT EXISTS "001"
CREATE SCHEMA IF NOT EXISTS "002schema"
CREATE SCHEMA IF NOT EXISTS "3_schema"

异常日志片段

Initializing Liquibase for schema 001
Creating database history table with name: "001".DATABASECHANGELOG
Liquibase ran for schema 001
..
Initializing Liquibase for schema 002schema
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibaseMultiTenant' defined in class path resource [com/company/app/data/liquibase/LiquibaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.LockException: liquibase.exception.DatabaseException: Schema "002SCHEMA" not found; SQL statement:
CREATE TABLE "002SCHEMA".DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID)) [90079-214] [Failed SQL: (90079) CREATE TABLE "002SCHEMA".DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID))]

已尝试的H2配置

配置1:

spring:
  datasource:
    platform: h2
    url: jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;DATABASE_TO_UPPER=false;
    driver-class-name: org.h2.Driver
    username: sa
    password:

配置2:

spring:
  datasource:
    platform: h2
    url: jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;DATABASE_TO_LOWER=true;CASE_INSENSITIVE_IDENTIFIERS=true;
    driver-class-name: org.h2.Driver
    username: sa
    password:

解决思路

  1. 精准配置H2标识符大小写规则

    • 确保DATABASE_TO_UPPER=false参数生效,PostgreSQL模式下H2对带双引号的标识符会保留原大小写,建议补充QUOTE_IDENTIFIERS=TRUE参数强制H2对所有标识符使用引号,避免自动转换:
      spring:
        datasource:
          url: jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;QUOTE_IDENTIFIERS=TRUE;CASE_INSENSITIVE_IDENTIFIERS=false;
      
    • H2 2.x版本中,CASE_INSENSITIVE_IDENTIFIERS=false会强制标识符大小写敏感,配合DATABASE_TO_UPPER=false能严格保留原标识符格式。
  2. 修正Liquibase对Schema名称的处理

    • 在Liquibase多租户配置(如liquibaseMultiTenant Bean)中,传递Schema名称时主动添加双引号,避免Liquibase自动将名称转为大写。
    • 配置Liquibase的quotedIdentifiers属性为true,让Liquibase对所有标识符使用引号包裹,保持原大小写格式。
  3. 验证Schema实际创建状态

    • 在启动失败前,通过H2控制台执行SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA,确认002schema是否按预期创建,排查是Schema创建阶段还是Liquibase处理阶段出现大小写转换问题。
  4. 适配H2版本特性

    • H2 1.4.200与2.x版本在标识符处理上存在差异,若使用1.4.200,可尝试添加IGNORECASE=FALSE参数增强大小写敏感性;若使用2.x版本,优先用DATABASE_TO_UPPER=false+QUOTE_IDENTIFIERS=TRUE组合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:05:21