
本文详解 Spring Boot 集成 H2 数据库时因 identity 关键字不兼容导致的 JdbcSQLSyntaxErrorException,提供符合 H2 2.0+ 规范的建表语句修正方案,并说明自增主键的正确声明方式。
本文详解 spring boot 集成 h2 数据库时因 `identity` 关键字不兼容导致的 `jdbcsqlsyntaxerrorexception`,提供符合 h2 2.0+ 规范的建表语句修正方案,并说明自增主键的正确声明方式。
在基于 Spring Boot 的 JDBC Template 教程实践中,许多开发者会在首次运行项目时遇到 org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement 错误。该错误通常发生在 Spring Boot 自动执行 schema.sql 初始化数据库结构阶段,核心原因在于:H2 数据库(尤其是 2.1.x 及以上版本)已弃用 integer identity NOT NULL 这类旧式写法,要求显式使用 GENERATED ALWAYS AS IDENTITY 或兼容的 BIGINT AUTO_INCREMENT 语法。
原始出错语句如下(不兼容 H2 2.1+):
CREATE TABLE course (
course_id integer identity NOT NULL,
title varchar(80) NOT NULL,
description varchar(500) NOT NULL,
link varchar(255) NOT NULL,
CONSTRAINT pk_course_course_id PRIMARY KEY (course_id)
);其中 integer identity 是 H2 1.4.x 的遗留语法,在 H2 2.x 中已被移除,解析器会报错并提示期望 GENERATED, AUTO_INCREMENT 等关键字。
✅ 正确写法(推荐,完全兼容 H2 2.1+ 和 Spring Boot 3.x 默认依赖):
CREATE TABLE course (
course_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
title VARCHAR(80) NOT NULL,
description VARCHAR(500) NOT NULL,
link VARCHAR(255) NOT NULL
);? 关键修改说明:
- 使用 BIGINT 替代 integer(更符合现代 H2 对自增列的类型推荐);
- 显式声明 GENERATED ALWAYS AS IDENTITY —— 这是 H2 官方标准语法,语义清晰且具备跨版本稳定性;
- 主键约束可直接内联于列定义后(PRIMARY KEY),无需额外 CONSTRAINT ... PRIMARY KEY (...) 从句,更简洁且避免冗余。
⚠️ 注意事项:
- 若你使用的是 Spring Boot 3.0+(默认集成 H2 2.2.x),绝对不要在 DDL 中使用 identity、auto_increment(MySQL 风格)或 serial(PostgreSQL 风格)等非标准关键字;
- schema.sql 文件必须位于 src/main/resources/ 目录下,且需确保 spring.sql.init.mode=always(Spring Boot 2.5+)或 spring.sql.init.mode=always + spring.sql.init.platform=h2(如需多平台适配)已在 application.properties 中启用;
- 若同时使用 data.sql 插入测试数据,请确保 schema.sql 执行完毕后再运行 data.sql,顺序由 Spring Boot 自动保障;
- 如需保留原 course_id 列名与逻辑,但避免手动维护 ID,切勿改用 DEFAULT + SEQUENCE 组合——GENERATED ALWAYS AS IDENTITY 已是最优解,自动处理序列生成与主键约束。
? 补充:验证是否生效
启动应用后,可通过 H2 Console(默认 http://localhost:8080/h2-console)连接 jdbc:h2:mem:testdb,执行 SELECT * FROM INFORMATION_SCHEMA.SEQUENCES; 查看 identity 序列是否已创建;再执行 INSERT INTO course(title, description, link) VALUES('Java Basics', 'Intro to Java', 'https://example.com/java'); 测试自增是否正常。
总结而言,该错误本质是 SQL 方言迁移问题,而非代码逻辑缺陷。掌握 H2 当前版本的 DDL 规范,能显著提升 Spring Boot 数据初始化的健壮性与可维护性。始终以 H2 官方文档 为权威参考,可有效规避同类语法陷阱。










