当前位置: 首页 > 知识库问答 >
问题:

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

张璞
2023-04-27

问题描述

开发时使用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]

共有2个答案

孔鸿哲
2023-04-27

User是H2的关键字呀

龚勇锐
2023-04-27

来自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).
下面是不能用作标识符的关键字列表(表名、列名等),除非它们被引号(用双引号括起来)。
image.png
给出的列表里面就包括了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文件,我不清楚你的情况是属于哪一种,但是这个问题应该是可以通过上面的措施解决的

 类似资料:
  • 看来PostgreSQL不允许创建名为'user'的数据库表。但MySQL将允许创建这样的表。 那是因为它是一个关键词吗?但是Hibernate无法识别任何问题(即使我们设置了PostgreSQL方言)。

  • 我有一个Spring boot应用程序,其中有H2作为数据库。我只有一个实体,。当我运行应用程序时,在内存中创建表时,会不断出现DDL错误。如果我试图通过浏览器访问H2控制台(),它将无法连接。我相信这是因为表格创建不成功。 到目前为止,我只添加了,,注释到我的实体。我甚至尝试将字段名称从(,)更改为(,)使用/,因为我认为id和name可能是保留的单词。然而,我一直得到相同的DDL错误 错误:

  • 示例类: 属性(源): 但是,每当我访问并单击Connect时,就会直接指向一个空白的白色页面。当我使用“测试连接”按钮时,它说“测试成功”。正如本问题中提到的,我尝试了JDBC:h2:mem:testdb和JDBC:h2:~/test来获取JDBC URL。 IDE控制台中不会显示错误。问题可能是什么?谢了。

  • 我想使用JavaFx、Spring Boot和Spring Data JPA制作一个桌面应用程序,并将H2作为我的数据库。问题是我试图运行JUnit以将数据保存在本地目录中,但每次运行JUnit时数据都会丢失。 我的文件; 我的测试用例; 打印列表的大小是1,但当我再次像这样运行测试用例时 它打印的列表大小为0

  • > 我希望所有表名都保持小写。示例 我使用Liquibase设置数据库,它看起来像 问题 如何告诉我的表都是小写->而不是?

  • 我试图用嵌入式数据库(H2)创建一个Spring Boot应用程序,并在应用程序启动时用liquibase创建数据,但绝对没有工作。 当我转到http://localhost:8080/h2-console/并尝试登录到jdbc:h2:mem:testdb时,我得到了 下面是我的资源/application.properties: