如何修复 org.h2.jdbc.JdbcSQLSyntaxErrorException:SQL 语句中的语法错误需要“标识符”

mak*_*ker 15 java hibernate h2 spring-boot

我正在为我的 springboot 应用程序使用 H2 内存数据库。我在哪里启用了hibernate.ddl-auto. 当休眠创建模式时,我遇到了异常

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException:
Syntax error in SQL statement "CREATE TABLE PRODUCT_OFFSET_INFO (ID BIGINT NOT NULL, MODIFIED_TIMESTAMP TIMESTAMP, OFFSET[*] BIGINT, TOPIC_NAME VARCHAR(255), PRIMARY KEY (ID))"; expected "identifier"; SQL statement:
create table PRODUCT_OFFSET_INFO (ID bigint not null, MODIFIED_TIMESTAMP timestamp, OFFSET bigint, TOPIC_NAME varchar(255), primary key (ID)) [42001-200]
'''
Run Code Online (Sandbox Code Playgroud)

下面是实体类:

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException:
Syntax error in SQL statement "CREATE TABLE PRODUCT_OFFSET_INFO (ID BIGINT NOT NULL, MODIFIED_TIMESTAMP TIMESTAMP, OFFSET[*] BIGINT, TOPIC_NAME VARCHAR(255), PRIMARY KEY (ID))"; expected "identifier"; SQL statement:
create table PRODUCT_OFFSET_INFO (ID bigint not null, MODIFIED_TIMESTAMP timestamp, OFFSET bigint, TOPIC_NAME varchar(255), primary key (ID)) [42001-200]
'''
Run Code Online (Sandbox Code Playgroud)

下面是数据库配置文件:

@Entity
@Table(name="PRODUCT_OFFSET_INFO")
public class ProductOffsetInfo implements Serializable
{
   private static final long serialVersionUID = -2147468513335906679L;
    
   @Id
   @Column(name="ID")
   private Long ProductId;
    
   @Column(name="TOPIC_NAME")
   private String topic_name;
    
   @Column(name="OFFSET")
   private Long offset;
    
   @Column(name = "MODIFIED_TIMESTAMP")
   private Date modified;
    
   public Long getProductId() {
       return ProductId;
   }
   public void setProductId(Long ProductId) {
       this.ProductId = ProductId;
   }
    
   public String getTopic_name() {
       return topic_name;
   }
   public void setTopic_name(String topic_name) {
       this.topic_name = topic_name;
   }
    
   public Long getOffset() {
       return offset;
   }
   public void setOffset(Long offset) {
       this.offset = offset;
   }
    
   public Date getModified() {
       return modified;
   }
    
   public void setModified(Date modified) {
       this.modified = modified;
   }
}
Run Code Online (Sandbox Code Playgroud)

以下是application.ymlDB的内容

    spring:
      profiles: mock
      jpa:
        database-platform: org.hibernate.dialect.H2Dialect
        generate-ddl: true
        hibernate:
          ddl-auto: create
      datasource:
        jdbcUrl: jdbc:h2:mem:PRODUCT
        driver-class-name: org.h2.Driver
        maximumPoolSize: 10
        minimumIdle: 5
        idleTimeout: 60000
        maxLifetime: 120000
        leakDetectionThreshold: 180000
        poolName: "product"

Run Code Online (Sandbox Code Playgroud)

Ste*_*rnK 19

尝试纠正这个问题:

@Column(name="OFFSET")
private Long offset;
Run Code Online (Sandbox Code Playgroud)

@Column(name="`OFFSET`")
private Long offset;
Run Code Online (Sandbox Code Playgroud)

作为OFFSET保留关键字,您应该通过在映射文档中将列名括在反引号中来强制 Hibernate 在生成的 SQL 中引用标识符。请参阅hibernate 文档的这一部分。

  • 由于另一个保留关键字,一个名为“user”的表,我遇到了同样的问题。 (4认同)
  • 在寻找了一整天为什么我的表没有在 H2 数据库中使用 Hibernate 创建后,我找到了这个答案。你太棒了!@sternk 在我的列名“key”处添加这些“终于成功了。该问题是在升级到 Spring Boot 2.5 和 H2 2.1.210 时出现的,之前运行良好。 (3认同)
  • 这也适用于表名,“User”是 H2 DB 中的保留键,我在 Spring Boot 项目启动期间以与答案中所述相同的方式解决了相同的异常。 (3认同)