🔖

h2.jdbc.JdbcSQLSyntaxErrorException: SQLステートメントに文法エラーがあります

2022/08/01に公開

H2 DB使用時に発生した文法エラーを解決する

問題

H2 DB使用時に文法エラーが発生し、SQLを実行できない。

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: SQLステートメントに文法エラーがあります "create table [*]user (id integer generated by default as identity, name varchar(255), primary key (id))"; 期待されるステートメント "identifier"
Syntax error in SQL statement "create table [*]user (id integer generated by default as identity, name varchar(255), primary key (id))"; expected "identifier"; SQL statement:

状況

SQLはJPAが自動生成している。

import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id

@Entity
data class User(
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	var id: Int = 0,
	var name: String = ""
)
import org.springframework.data.repository.CrudRepository

interface UserRepository : CrudRepository<User, Int>

原因

エラー文中の[*] はこの周辺に問題があることをしめしている。
今回は[*]userなので、user周辺に問題がある事がわかる。
そして「user」はH2の予約後であるので、クォート等で囲う必要がある。
http://www.h2database.com/html/advanced.html#keywords

解決

SQLで用いる識別子をクォートする設定を使う。

spring.jpa.properties.hibernate.globally_quoted_identifiers=true
spring.jpa.properties.hibernate.globally_quoted_identifiers_skip_column_definitions = true

あるいは接続時の設定にNON_KEYWORDSを設定する事で回避もできる。

spring.datasource.url=jdbc:h2:mem:testdb;NON_KEYWORDS=USER

ただし、公式のドキュメントによると「可能であれば、引用符付きの識別子」を使用してほしいとのこと。
https://www.h2database.com/html/commands.html#set_non_keywords

なので、globally_quoted_identifiersを使うのが良さそう。

GitHubで編集を提案

Discussion