使用JOINED继承策略时出现SQLSyntaxErrorException问题求助
问题根源与解决方法
你遇到的问题核心是**procedure是MySQL的保留关键字**,直接用它作为表名会触发SQL语法解析错误。
为什么会报错?
MySQL中procedure是用于定义存储过程的关键字,当Hibernate生成的SQL语句里直接写from procedure dentalproc0_1_时,MySQL会误把procedure当成SQL语法的一部分(而非表名),从而抛出语法错误提示。
解决步骤
方案1:给关键字表名添加反引号转义(快速修复)
修改父实体MedicalProcedure的@Table注解,用反引号包裹表名,明确告诉MySQL这是一个表名而非关键字:
@Entity @Table(name = "`procedure`") // 用反引号包裹关键字表名 @Inheritance(strategy = InheritanceType.JOINED) public class MedicalProcedure{ // 原有代码保持不变 }
你的建表语句已经用了反引号(CREATE TABLE procedure (...)),这部分无需修改,因为已经正确转义了表名。
方案2:更换非关键字表名(更稳妥的长期方案)
如果不想依赖关键字转义,建议把表名改成语义化的非保留字,比如medical_procedure:
- 修改实体类:
@Entity @Table(name = "medical_procedure") @Inheritance(strategy = InheritanceType.JOINED) public class MedicalProcedure{ // 原有代码保持不变 } @Entity @Table(name = "dental_procedure") // 子类表名也同步优化 public class DentalProcedure extends MedicalProcedure { // 注意:子类不需要重复定义@Id!父类已定义主键,JOINED策略下子类主键自动关联父表外键,重复定义会导致冲突 @Column(name = "data") private String data; }
- 更新建表语句:
CREATE TABLE `medical_procedure` ( `id` int(11) NOT NULL AUTO_INCREMENT, -- 建议添加AUTO_INCREMENT,匹配实体类的@GeneratedValue `patient_id` int(11) DEFAULT NULL, `doctor_id` int(11) DEFAULT NULL, `date` date DEFAULT NULL, `time` time DEFAULT NULL, -- 注意:实体类是TemporalType.TIME,建表时要对应time类型(原语句用了date,会导致类型不匹配) PRIMARY KEY (`id`), KEY `FK_PATIENT_ID_idx` (`patient_id`), KEY `FK_DOCTOR_ID_idx` (`doctor_id`), CONSTRAINT `FK_DOCTOR_ID` FOREIGN KEY (`doctor_id`) REFERENCES `person` (`id`), CONSTRAINT `FK_PATIENT_ID` FOREIGN KEY (`patient_id`) REFERENCES `person` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `dental_procedure` ( `id` int(11) NOT NULL, `data` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`), CONSTRAINT `PK_DENTAL_PROCEDURE_ID` FOREIGN KEY (`id`) REFERENCES `medical_procedure` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
额外注意事项
- 子类
DentalProcedure无需重复定义@Id字段:JOINED继承策略下,子类的主键同时作为父表的外键,父类已定义主键,子类继承即可,重复定义会导致Hibernate映射错误。 - 修正
time字段类型:实体类中time字段标注了TemporalType.TIME,但原建表语句用了date类型,这会导致数据类型不匹配,建议改成time类型。
验证修改
完成上述修改后,重新运行DAO的getAll方法,Hibernate会生成正确解析的SQL语句,MySQL就能正常执行查询,不会再抛出语法错误。
内容的提问来源于stack exchange,提问作者bwylegly
相关产品推荐
相关产品推荐

