エラーの内容
Spring Bootで、Spring Data JPA
とMySQL Driver
を使った開発を行っていたところ
以下のようなエラーメッセージが表示されました。
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near…
SQL文に問題があるよって言われてるみたいだけど、JPA使ってるからSQL文なんて書いた覚えがない・・・
エラーが発生したソースコード
今回は、JPAのsaveメソッドを使って
MySQL側で用意したテーブルにinsertしようとしたら、上記のエラーが発生しました。
実装してエラーが発生したコードは以下の内容になります。
YAML
接続情報を定義しています。
spring:
datasource:
url: jdbc:mysql://localhost:3306/jpa_db?serverTimezone=JST
username: qiita
password: qiita
driver-class-name: com.mysql.jdbc.Driver
Repostiory
org.springframework.data.jpa.repository.JpaRepository
を継承したインタフェースを定義しています。
package com.example.jpamysql.repository;
import com.example.jpamysql.domain.GroupEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface GroupRepository extends JpaRepository<GroupEntity, Long> {
}
Service
String型で受け取った引数をEntityクラスのオブジェクトにセットして
JPAのsaveメソッドに渡しています。
package com.example.jpamysql.service;
import com.example.jpamysql.domain.GroupEntity;
import com.example.jpamysql.repository.GroupRepository;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class GroupService {
private final GroupRepository groupRepository;
public void save(String name) {
GroupEntity group = new GroupEntity();
group.setName(name);
groupRepository.save(group);
}
}
Entity
テーブルの項目を定義したクラスです。今回はnameにだけinsertするので、descriptionはあらかじめMySQLの方でNULLを許容する設定にしています。
package com.example.jpamysql.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "groups")
public class GroupEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", columnDefinition = "VARCHAR(20)")
private String name;
@Column(name = "description", columnDefinition = "VARCHAR(45)")
private String description;
}
解決策
application.yml
の設定を変えたり、MySQL側で作成したテーブルの設定を変えてみたりしましたが、今回のエラーには関係がありませんでした。
Entityのクラスで@Table
で定義しているテーブル名をバッククォーテーションで囲うと解決しました。
package com.example.jpamysql.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "`groups`") //テーブル名をバッククォーテーションで囲う
public class GroupEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", columnDefinition = "VARCHAR(20)")
private String name;
@Column(name = "description", columnDefinition = "VARCHAR(45)")
private String description;
}
MySQLではテーブル名をバッククォーテーションで囲ってあげなきゃいけないみたいですね。
(ずっとPostgreSQLを使っていたから知らなかった!!)
もしかしたらMySQLのバージョンにも寄るかもしれません。
私が使っていたのはMySQL Ver 8.0.2
でした。
必ずしもテーブル名をバッククォーテーションで囲まなきゃいけない訳ではないのですが
今回のテーブル名である groups は、MySQL Ver 8.0.2
以降では予約語に相当するので
バッククォーテーションで囲う必要があったようです。
参考記事
- [【MySQL】ERROR 1064 (42000)を解消する](https://qiita.com/hiro266/items/c8d9eaff46fcd08dacc5)
- [MYSQL バッククオートについて](https://qiita.com/masa_stone22/items/c3ea3b1d81f5d39c7323)
- [キーワードと予約語](https://dev.mysql.com/doc/refman/8.0/en/keywords.html)