### JPA/Hibernate 命名策略:孤立单大写字母陷阱 Spring Boot 默认的 `SpringPhysicalNamingStrategy` 把驼峰转蛇形时,**会把"孤立的单个大写字母"当成缩略语(同 `URL` / `ID` 处理),不插下划线**。触发条件:某个大写字母的**左侧是小写或字符串开头、右侧是大写或字符串结尾**。 这会导致 Hibernate 建表的物理列名与 MyBatis-Plus 生成 SQL 时的列名(走 `camelToUnderscore`)**不一致**,报错形如: ``` java.sql.SQLSyntaxErrorException: Unknown column 'party_a_clear' in 'field list' ``` 已知踩坑记录: | Java 字段 | 期望列名 | Hibernate 实际建成 | MyBatis SQL 写的 | |---|---|---|---| | `partyA` | `party_a` | `partya` ❌ | `party_a` | | `partyAClear` | `party_a_clear` | `partyaclear` ❌ | `party_a_clear` | **规则**:Java 字段名里出现下述形态的**孤立单大写字母**时,**必须**在 `@Column` 上显式写 `name="蛇形列名"` 钉死: - 结尾单大写:`xxxA`、`xxxB`、`xxxZ` - 夹在小写与大写词之间的单大写:`xxxAYyy`、`xxxBClear` - 连续单大写:`xxxABC`(会整段当缩略语,不断词) 反例(**这些形态不会踩坑,无需 `@Column(name=...)`**): - `ownerUserId` → `owner_user_id` ✅(`Id` 是两字符段,按普通词处理) - `bidForm` → `bid_form` ✅(`Form` 是完整词) - `provinceCode` → `province_code` ✅ **修复模板**: ```java @Column(name = "party_a_clear", columnDefinition = "tinyint not null default 0 comment '甲方是否明确'") private Integer partyAClear = 0; ``` **为什么不换命名策略**:换策略会影响全部已建对的列(几十列),代价远大于给个位数问题字段加 `@Column(name=...)`。 **为什么线上很久才暴露**:`ddl-auto: update` 只加列不改列。老字段可能长期只走 SELECT(`ResultMap` 兜住)不写入,直到某天走 INSERT/UPDATE 才炸。**新加 Java 字段时**如果撞规则,第一次持久化就会报 `Unknown column`。 **新增字段检查清单**(写完 entity、跑起来之前): 1. 字段名里有没有孤立单大写字母?没有 → 直接过。 2. 有 → 加 `@Column(name = "snake_case_name", columnDefinition = "...")`。 3. `ddl-auto: update` 环境下,如果表已经存在且字段名撞过坑,需要一条 `ALTER TABLE t CHANGE 旧列名 新列名 类型 ...;` 手工迁移,Hibernate 不会自动改名。