그 외 공부/트러블 슈팅

MySQL 예약어 사용으로 인한 JPA 데이터베이스 자동 생성 실패 문제

SeongOnion 2022. 7. 28. 20:37
728x90

문제 상황

스프링 + JPA에 MySQL을 연결해 사용하는 상황에서 “Group”이라는 엔티티를 정의한 후, yml 파일의 jpa.hibernate.ddl-auto 설정을 create로 하여 엔티티 정보에 따라 테이블을 jpa가 자동으로 생성하도록 처리해주었다.

spring:
  jpa:
    hibernate:
      ddl-auto: create # 테이블 자동 생성
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    database: mysql

하지만 서버를 켰을 때, SQL syntax error로 인해 “group” 테이블을 생성하는데 실패했다는 메시지를 뿜으며 테이블이 제대로 생성되지 않았다.

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table group (id bigint not null auto_increment, explanation varchar(255), name varchar(255), primary key (id)) engine=InnoDB" via JDBC Statement
Caused by: 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 'group (id bigint not null auto_increment, explanation varchar(255), name varchar' at line 1

 

원인 파악

테이블 작성에 대한 쿼리를 내가 직접 짠게 아닌데 syntax error가 떠서 대체 뭘 어떻게 해야하나 싶었다.

 

실제로 연결된 MySQL을 살펴보니, 다른 테이블들은 정상적으로 생성이 됐는데 group 테이블만 생성이 되지 않은 상태였다.

 

얼마간의 삽질 후에 알아낸 원인은 ‘group’이 MySQL에서 사용하는 예약어였기 때문이다..

MySQL :: MySQL 8.0 Reference Manual :: 9.3 Keywords and Reserved Words

 

MySQL :: MySQL 8.0 Reference Manual :: 9.3 Keywords and Reserved Words

9.3 Keywords and Reserved Words Keywords are words that have significance in SQL. Certain keywords, such as SELECT, DELETE, or BIGINT, are reserved and require special treatment for use as identifiers such as table and column names. This may also be true

dev.mysql.com

CREATE TABLE group 테이블 생성 쿼리에서 group을 테이블명으로 인식하지 못하고 예약어로 사용하게 됐고, 따라서 Syntax error가 발생한 것이다.

 

해결방안

엔티티 객체에 테이블명을 따옴표로 감싸 재정의해줌으로써 문제를 해결할 수 있었다.

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
@Table(name = "\"group\"") // 테이블명 따옴표로 처리
public class Group {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String explanation;

}

 

그 밖에 repository에서 @Query 를 사용해 JPQL을 정의해준 경우에도, 테이블에 대한 alias를 예약어로 사용하면 Syntax error가 발생할 수 있다.

// 예약어 관련 Syntax error 발생
@Repository
public interface GroupRepository extends JpaRepository<Group, Long> {

    @Query("SELECT group from Group AS group where group.name = :name")
    Optional<Group> findByName(@Param("name") String name);

}
// 정상적으로 작동
@Repository
public interface GroupRepository extends JpaRepository<Group, Long> {

    @Query("SELECT g from Group AS g where g.name = :name")
    Optional<Group> findByName(@Param("name") String name);

}