ERROR

Spring Boot 2.5 Hibernate data.sql 에러

마이구미2 2021. 10. 6. 19:48

패스트캠퍼스 온라인 강의 수강 중

data.sql 파일을 통해 데이터를 미리 입력해 JPA repository 의 동작과 쿼리 생성에 대해 테스트하는 예제를 해보았다.

선생님과 똑같이 했는데 다음과 같은 에러가 발생했다.

 

Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: 

Failed to execute SQL script statement #1 of URL 

[file:/C:/Users/user/IdeaProjects/bookmanager/build/resources/test/data.sql]: 

call next value for hibernate_sequence; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: 

Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-200]

 

hibernate_sequence 가 만들어지지 않은 것이 문제라고 생각해서 spring hibernate 등등을 구글링했고, 원인을 발견했다.

Spring Boot 2.5 버전을 사용하는 사람들에게 이 부분에서 같은 문제가 생긴 것 같았다.

 

 

Spring Boot 공식 문서

Hibernate and data.sql
By default, data.sql scripts are now run before Hibernate is initialized. This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase. If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true. While mixing database initialization technologies is not recommended, this will also allow you to use a schema.sql script to build upon a Hibernate-created schema before it’s populated via data.sql.

 

정리하자면,

Spring Boot 2.5 버전부터는 data.sql 이 Hibernate 가 초기화되기 전에 실행되어

Hibernate 초기화를 통해 생성된 스키마에 데이터를 입력하기 위해 data.sql 을 실행하려면

1) application.properties(yml) 에 spring.jpa.defer-datasource-initialization = true 를 추가

2) schema.sql을 추가 (권장하지 않음)

해야 한다.

 

 

이 방법을 따라 application.yml 을 수정했다.

spring:
  h2:
    console:
      enabled: true
  jpa:
    defer-datasource-initialization: true
    show-sql: true
    properties:
      hibernate:
        format_sql: true
server:
  port: 8070

 

 

 

그런데 이번에는 또 다른 에러가 발생했다.

 

Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException:

Failed to execute SQL script statement #2 of URL [file:/C:/Users/user/IdeaProjects/bookmanager/build/resources/test/data.sql]:

insert into user ('id', 'name', 'email', 'createdAt', 'updatedAt') values (1, 'aaa', 'abc@fastcampus.com', now(), now()); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException:

Syntax error in SQL statement "INSERT INTO USER ('id'[*], 'name', 'email', 'created_at', 'updated_at') VALUES (1, 'aaa', 'abc@fastcampus.com', NOW(), NOW())";

expected "identifier"; SQL statement:
insert into user ('id', 'name', 'email', 'created_at', 'updated_at') values (1, 'aaa', 'abc@fastcampus.com', now(), now()) [42001-200]

 

이번엔 sql 쿼리문에서 에러가 발생한 것 같았다. 찾아보니 expected "identifier" 이 문제는 대부분 예약어가 쿼리문에 들어있어서 발생하는 것이었는데, 내가 작성한 쿼리문에서 나는 뭐가 문제인지 알 수가 없었다.

 

이것 저것 찾아보고 해보다가 혹시 values 뒤에 내가 바꾸어 작성한 부분에 문제가 있나 싶어 결국 제일 하기 싫었던 선생님이 작성한 내용 복붙하기를 했다.

 

 

붙여넣기 하자마자 색, 폰트, 기울기 다 다르게 나와서 이때부터 이게 뭔지에 대해서만 검색했따.

(IntelliJ 에게 무한한 감사를 ~~ ..)

 

 

뭐가 다른지 자세히 보니 따옴표 모양이 달랐다. 젠장

# 선생님이 작성한 쿼리문
call next value for hibernate_sequence;
insert into user (`id`, `name`, `email`, `created_at`, `updated_at`) values (1, 'martin', 'martin@fastcampus.com', now(), now());

# 내가 작성한 쿼리문
call next value for hibernate_sequence;
insert into user ('id', 'name', 'email', 'created_at', 'updated_at') values (1, 'aaa', 'abc@fastcampus.com', now(), now());

이렇게 보면 정말 모를 것 같다.

 

 

휴... 그래서 정말 화가 났지만 이것이 무슨 차이인지 찾아보았다.

` <- 요 아이의 이름은 grave accent 로 backtick, backquoto 등의 이름으로도 불리며 우리말로는 억음부호 라고 한다.

키보드에는 물결 ~ 표시와 함께 위치해있다.

 

언제 사용하는 건지 알아보니 보통 JavaScript 에서 사용하는 듯 했고, 

Spring 관련해서는 SQL 예약어에서 탈출할 때 사용한다고 한다.

 

 

SQL 예약어 탈출 방법

1) JPA 컬럼 이름에 큰따옴표 기호(") 사용  ex) "\"order\""

2) Hibernate 고유 backtick 문자(`) 사용  ex) "`order`"

3) persistence.xml 파일의 hibervate.globally_quoted_identifiers property를 true 로 설정

4) application.properties(yml) 에 spring.jpa.properties.hibernate.globally_quoted_identifiers = true 추가

 

 

저 작은 부호 하나 때문에 거의 1시간을 날렸지만....... 새로운 지식을 습득하는데 이정도 시간이면 조금이라고 생각하고 넘어가기로 했다.

 

 

backtick 부호를 사용해서 다시 실행하니 정상적으로 작동했다 ^^

 

다른 방법은 또 다른 경우에 사용하는 건지 잘안됐다. 너무 힘들어서 이만 넘어가기로 했다.

 

 

 

마지막으로 서로 다른 작은 따옴표 부호들 첨부하며 마칩니다.

 

 

참고

https://velog.io/@khsb2012/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-2.5-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-hibernate-data.sql-%EA%B4%80%EB%A0%A8-%EB%B3%80%EB%8F%99%EC%82%AC%ED%95%AD

https://velog.io/@sunaaank/js-backtick

https://www.chrouki.com/posts/escape-sql-reserved-keywords-jpa-hibernate/