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

Spring Data JPA(H2数据库)在创建表时返回DDL错误

东门晓博
2023-03-14

我有一个Spring boot应用程序,其中有H2作为数据库。我只有一个实体,User。当我运行应用程序时,在内存中创建表时,会不断出现DDL错误。如果我试图通过浏览器访问H2控制台(localhost:8080/H2 console),它将无法连接。我相信这是因为表格创建不成功。

到目前为止,我只添加@Entity@Id@GeneratedValue注释到我的User实体。我甚至尝试将字段名称从(idname)更改为(userIduserName)使用@Colzo(name="user_id")/@Colzo(name="user_name"),因为我认为id和name可能是保留的单词。然而,我一直得到相同的DDL错误

错误:

由以下原因引起:org.h2.jdbc.JdbcSQLSynTaxErrorExctive:SQL语句"DROP TABLE IF EXISTS USER[*]CASCADE"中的语法错误;预期的"标识符";SQL语句:如果存在用户CASCADE,则删除表[42001-206]

2022-01-21 14:28:13.618WARN 20700 --- [ restartedMain]o. h. t. s. i. ExceptionHandlerLoggedImpl: GenerationTarget遇到异常接受命令:通过JDBC语句执行DDL“创建表用户(id整数不为空,birth_date时间戳,名称varchar(255),主键(id)”时出错

org.hibernate.tool.schema.spi.命令接受异常:通过JDBC语句执行DDL“创建表用户(id整数不为空,birth_date时间戳,名称varchar(255),主键(id))”时出错

原因:org。h2。jdbc。JdbcSQLSyntaxErrorException:SQL语句“CREATE TABLE USER[*](ID INTEGER不为NULL,出生日期时间戳,NAME VARCHAR(255),PRIMARY KEY(ID))”中的语法错误;预期的“标识符”;SQL语句:在org上创建表用户(id integer not null,birth_date timestamp,name varchar(255),primary key(id))[42001-206]。h2。消息DbException。getJdbcSQLException(DbException.java:521)~[h2-2.0.206.jar:2.0.206]

用户类

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(description="some description here")
@Entity
public class User {
    @Id
    @GeneratedValue
    private Integer id;
    
    @Size(min=2, message="Name should have at least 2 characters")
    @ApiModelProperty(notes="Name should have at least 2 characters")
    private String name;
    
    @Past
    @ApiModelProperty(notes="Birthdate should be in the past")
    @Column(name="birth_date")
    private Date birthDate;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", birthDate=" + birthDate + "]";
    }

    public User() {}
    
    public User(Integer id, String name, Date birthDate) {
        super();
        this.id = id;
        this.name = name;
        this.birthDate = birthDate;
    }
}

波姆。xml依赖关系

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <!-- <version>2.6.2</version> -->
    <version>2.5.2</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.0.206</version>
    <scope>runtime</scope>
</dependency>

application.properties

logging.level.org.springframework = info
spring.jackson.serialization.write-dates-as-timestamps=false
management.endpoints.web.exposure.include=*

spring.security.user.name=someusername
spring.security.user.password=somepassword

spring.jpa.show-sql=true
spring.h2.console.enabled=true

共有2个答案

丁沛
2023-03-14

更新:我认为有几个因素可能会影响这一点。方言——在org上,backticks似乎不再适用于我。冬眠地方话或组织。冬眠地方话后希腊方言。

然而,转义双引号对com有效。h2数据库:h2:1.4.200,但不在com上。h2database:h2:2.1.210,它似乎支持删除版本控制时看到的内容(默认为较低的临时Hibernate版本)。

当我在Hibernate版本2.1.210上运行你的代码时,我也看到了这一点。你使用了关键词/保留词中的保留字。我以前使用过三种解决方案。

这是一个常见问题,尤其是对于通用表名,例如组、顺序、大小写等。。

如果您对保留名称感兴趣,可以使用以下两种方法之一:

@表(名称=“用户”)

@Table(name="`user`") - may not work

或者,使用全局引用标识符属性:

hibernate.globally_quoted_identifiers=true

使用这些将允许您转义SQL保留字-。我只有一张桌子有这个问题,所以滴答声适合我。通过打开sql准备语句和格式设置,可以验证输出是否正确:

spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true

这将是一个很好的功能,要求能够在validate下拥有这样的属性:

hibernate.hbm2ddl.auto=validate

如果你有兴趣提交一个bug,你可以在他们的网站上创建一个测试用例并提交,请在这里输入链接描述。

对我来说奇怪的是为什么从maven pom中删除你的版本会奏效。。。这是奇怪的行为。通过将此功能添加到validate属性并检查classloader并循环表名(),可以很容易地预先验证这一点。

云宝
2023-03-14

我认为表名“USER”是保留的。如果您使用@Table(name=“”)注释将其更改为“_USER”或“CUSTOM_USER”,则可以使用。

 类似资料:
  • 我正在尝试创建一个新的JavaDB。我已经将Java DB驱动程序添加到库中,但在服务下创建新数据库时,它仍然会抛出一个错误。 我下载并定义了db-derby-10.15.2.0-bin 我在这里定义了drover文件 我在这里单击了创建数据库 填了这张表 点击om后显示如下 谁来帮帮我

  • org.h2.jdbc.jdbcsqlsyntaxerrorexception:SQL语句“create TABLE HIBERNATE_SEQUENCE(NEXT_VAL BIGINT)engine=[*]myisam”中存在语法错误;应为“标识符”

  • 我想创建一个简单的容器,其中包含一个带有初始化数据库的MySQL服务器。我的Dockerfile目前如下所示: 但是,当我通过我得到以下错误: 当我注释要创建数据库的行时(

  • 我想在springboot中通过H2创建表,但运行时出现以下错误:; 组织。冬眠地方话方言:hh000400:使用方言:org。冬眠地方话H2方言组织。冬眠工具模式。spi。CommandAcceptanceException:通过JDBC语句执行DDL“创建表bank_account(id bigint not null,balance double not null,full name var

  • 得到错误"表客户已经存在"当我试图创建一个表在H2内存数据库使用schema.sql.我使用的是Spring启动版本:2.5.4和以下是我的pom.xml.它的工作正常,如果我使用Spring启动版本:2.4.3 这是我的代码: 当我启动应用程序时,我收到以下错误。如何强制H2使用schema.sql创建表格? 原因:io。r2dbc。spi。R2dbcBadGrammarException:表“

  • 问题内容: 我想在Oracle数据库中创建一个临时表 就像是 在SQL Server中 然后用选择语句填充它 是否有可能? 谢谢 问题答案: 是的,Oracle有临时表。这是描述它们的AskTom文章的链接,这是oracle的官方CREATE TABLE文档。 但是,在Oracle中,只有临时表中的 数据 是临时的。该表是其他会话可见的常规对象。在Oracle中频繁创建和删除临时表是一种不好的做法