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

Spring Boot中Entity命名引发SQL语法错误的原因探究

问题描述

在Spring Boot RESTful API开发中,将User.java作为JPA Entity类时触发SQL语法错误,错误信息如下:

Syntax error in SQL statement "create table [*]user (userid bigint generated by default as identity, user_name varchar(20), primary key (userid))"; expected "identifier"; SQL statement:

将Entity类名称修改为UserEntity.java后,错误消失。想知道仅修改类名就能解决问题的原因。

相关代码与配置

原Entity类(User.java)

package com.example.demo.rest;

import com.fasterxml.jackson.annotation.JsonProperty;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonProperty("userId")
    private Long userId;
    
    @JsonProperty("userName")
    private String userName;

}

application.properties配置

spring.datasource.driverClassName:org.h2.Driver
spring.datasource.url:jdbc:h2:mem:test
spring.datasource.username:sa
spring.datasource.password:
spring.h2.console.enabled:true

spring.jpa.hibernate.ddl-auto=update

spring.jpa.defer-datasource-initialization=true

spring.mvc.pathmatch.matching-strategy = ANT_PATH_MATCHER

springdoc.api-docs.path=/api-docs
springdoc.swagger-ui.path=/swagger-ui.html

build.gradle配置

plugins {
    id 'java'
    id 'war'
    id 'org.springframework.boot' version '3.0.6'
    id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-data-rest'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.h2database:h2'
    annotationProcessor 'org.projectlombok:lombok'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}
原因分析

根本原因是User是H2数据库的保留关键字。JPA默认会用Entity类名作为数据库表名,当类名为User时,Hibernate生成的建表语句会直接使用user作为表名,而H2数据库不允许用保留关键字作为标识符(如表名、列名),因此触发SQL语法错误。

修改类名为UserEntity后,对应的表名变为user_entity,不属于保留关键字范畴,因此建表语句能正常执行。

替代解决方案

如果不想修改Entity类名,还可以通过以下方式处理:

  • 在@Entity注解中指定表名,避开保留关键字:
    @Entity(name = "app_user")
    public class User {
        // ... 类内容
    }
    
  • 配置Hibernate自动转义保留关键字,在application.properties中添加:
    spring.jpa.properties.hibernate.globally_quoted_identifiers=true
    
    开启后Hibernate会自动给所有标识符(表名、列名)添加引号,将保留关键字作为普通标识符使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:58:13