Oracle关键字冲突时必须用双引号转义,如@Column(name = "\"ONLINE\""),因Hibernate默认大写字段名触发保留字校验,未转义则建表报ORA-00904;且需配Oracle方言与ddl-auto=update。

直接加双引号,用 @Column(name = "\"ONLINE\"") 或 @Table(name = "\"ORDER\"") 包裹关键字列名/表名,这是 Oracle 场景下最稳妥、最通用的解法。
Oracle 关键字冲突时为什么不能只改字段名?
你改了 Java 字段名(比如从 order 改成 orderNo),但数据库建表语句仍可能生成 ORDER 列——因为 Hibernate 默认把字段名转大写后直接当列名用,而 ORDER 是 Oracle 保留字,建表就会报 ORA-00904 或 ORA-00922。更麻烦的是,有些字段名(如 level、condition)在旧版 Oracle 里不算严格保留字,但出现在 GROUP BY 或视图定义里会突然失效,排查成本极高。
- Oracle 对大小写敏感:未加引号的标识符自动转为大写,且不区分大小写匹配;加双引号后才严格按字面量处理
-
@Column(name = "ONLINE")不起作用——Hibernate 仍会把ONLINE当普通名传给 Oracle,触发关键字检查 - 必须写成
@Column(name = "\"ONLINE\""),让生成的 DDL 变成CREATE TABLE ... ("ONLINE" VARCHAR2(50))
实体类上 @Table 和 @Column 的双引号写法差异
Oracle 要求双引号是 SQL 字面量的一部分,所以 Java 字符串里得用反斜杠转义。但 @Table 和 @Column 对引号的处理逻辑一致,写法完全相同:
- 表名含关键字:
@Table(name = "\"ORDER\"") - 列名含关键字:
@Column(name = "\"LEVEL\"") - 联合使用没问题:
@Table(name = "\"GROUP\"", schema = "\"HR\"")—— 注意 schema 也要加引号,否则HR.GROUP中的GROUP仍会冲突 - 别用单引号或不转义:
"'ORDER'"或"ORDER"都无效,前者被当字符串值,后者触发关键字校验
DDL 自动创建时引号没生效?检查这几个点
即使写了双引号,启动后建表仍失败,大概率卡在配置或方言环节:
-
spring.jpa.hibernate.ddl-auto必须设为create或update,none或validate下不会执行建表 - Hibernate 方言必须明确指定:
spring.jpa.database-platform=org.hibernate.dialect.OracleDialect(Spring Boot 2.x)或org.hibernate.dialect.oracle.OracleDialect(3.x+),否则可能 fallback 到通用方言,忽略 Oracle 引号规则 - 如果用了 H2 做测试库,
MODE=Oracle参数必须带:jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle,否则 H2 不识别双引号语法 - 实体类没被扫描到也会静默跳过建表——确认
@EntityScan路径覆盖了该类,或启动类与实体在同包或子包下
双引号方案看似简单,但容易漏掉转义或方言配置;一旦漏掉,错误不会立刻暴露,而是等到首次查询才报 ORA-00904。真正上线前,务必用 SQL*Plus 直连验证生成的 DDL 是否真带了双引号。


















