Spring-Boot-Data-JPA使用H2数据库为什么无法创建表名为User的表?User是H2数据库的关键字吗?

问题描述

开发时使用Spring-Boot-Data-JPA操作H2数据库,创建表名为User的表失败
H2中用于保存用户的表是Users,表名应该没有冲突,User是H2数据库的关键字吗?
JPA生成的SQL代码中被@Id注释的username字段没有被指定为identifier,但是仅更改表名后可以就正常创建,其他表也都没有这个问题

问题出现的环境背景及自己尝试过哪些方法

Spring-Boot 2.7.11
Spring-Boot-Data-JPA
H2数据库
Eclipse + Spring Tools

相关代码

@Entity

@Data

@AllArgsConstructor

@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)

public class User {

@Id

private String username;

private String password;

}

你期待的结果是什么?实际看到的错误信息又是什么?

期待的结果是正常创建User表,但实际会报错
报错如下(有省略)

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table if exists user CASCADE " via JDBC Statement

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "drop table if exists [*]user CASCADE "; expected "identifier"; SQL statement:

drop table if exists user CASCADE [42001-214]

2023-04-24 15:04:27.375  WARN 10816 --- [ restartedMain] o.h.t.s.i.ExceptionHandlerLoggedImpl  : GenerationTarget encountered exception accepting command : Error executing DDL "create table user (username varchar(255) not null, password varchar(255), primary key (username))" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table user (username varchar(255) not null, password varchar(255), primary key (username))" via JDBC Statement

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "create table [*]user (username varchar(255) not null, password varchar(255), primary key (username))"; expected "identifier"; SQL statement:

create table user (username varchar(255) not null, password varchar(255), primary key (username)) [42001-214]


回答:

来自H2官方文档:
H2的关键字
里面明确说明:
There is a list of keywords that can't be used as identifiers (table names, column names and so on), unless they are quoted (surrounded with double quotes).
下面是不能用作标识符的关键字列表(表名、列名等),除非它们被引号(用双引号括起来)。

给出的列表里面就包括了user,所以尝试在你建表的时候把表名用双引号括起来试试看
事实上你给出的错误信息里也可以证实这一点,你有没有发现drop table if exists user这一句报错信息里drop if exists user都是红色的?这说明了它们都是关键字。
补充:
(stackOverFlow的回答)[https://stackoverflow.com/questions/70797504/spring-data-jpa-h2-database-is-returning-ddl-error-during-table-creation]
这篇回答是和你一样的情况:
基本上提出了几种可能:
1.你的pom.xml中引入的h2数据库版本不对,没有成功引入h2
2.如果不是1,解决方法比较通用的是使用

@Table(name = "\"user\"")

或者

@Table(name = "`user`")

加在实体类上面
3、似乎从h2的v2.1.x版本后user作为关键字被确定了下来
之前的版本则没有这个问题
4、有人已经把这个问题作为issues提交给了hibernate官方:
(https://hibernate.atlassian.net/browse/HHH-15079)
官方的建议是暂时参阅:
(https://docs.jboss.org/hibernate/stable/orm/userguide/html_si...)的第26.6.3节:
即设置:

hibernate.globally_quoted_identifiers=true

这样做默认给所有的表名都加上引号来规避关键字的情况
有一个老哥表示这样写也会给正常的表名加上引号,并可能引入更多错误,他推荐这样配置:

spring.jpa.properties.hibernate.auto_quote_keyword=true

5、你贴出的文章例子里的实体类上标明了@Table(name="user"),你的似乎没有,考虑一下加上,如果不行请采用上面的转义写法
6、你没有贴出你的配置和pom.xml文件,我不清楚你的情况是属于哪一种,但是这个问题应该是可以通过上面的措施解决的


回答:

User是H2的关键字呀

以上是 Spring-Boot-Data-JPA使用H2数据库为什么无法创建表名为User的表?User是H2数据库的关键字吗? 的全部内容, 来源链接: utcz.com/p/945132.html

回到顶部