Skip to content

Bug in creating bean with name 'dataSourceScriptDatabaseInitializer'

Jack edited this page Mar 27, 2022 · 1 revision

Spring initialization by files

Spring Boot 는 Application 실행 시, 약속된 Naming 의 파일이 exists == true 경우 그에 맞는 동작을 수행합니다. Spring Boot 의 기본으로 널리 알려져 있는 application.properties(application.yaml) 이 대표적입니다. 여기서는 Spring Data 에서 약속된 shema.sqldata.sqldata.sql 에 관한 버그를 확인하여 공유합니다. 참고로 제가 사용한 환경은 spring boot 2.6.2 + mysql image (22.03.28 기준 latest) 를 사용했습니다.

Spring config for datasource initialization

Spring Boot 에서 위 파일을 통한 동작에서 조심할 점은 각 초기화가 Queue 형식으로 Chaining 된다는 것입니다. 예를 들어 Spring Data 의 Repository 로 ddl-auto : create-drop 일 경우, API 실행시 DDL 일 실행됩니다. 이때 data.sql 파일이 존재한다면 DDL 시점보다 datasource initialization 이 후순위로 동작해야 정상적인 결과를 얻을 수 있습니다. 하지만, spring boot 2.6.x 부터는 datasource initialization 은 DDL 기능보다 앞서 동작하도록 변경되어 위와 같은 경우에 추가 설정이 필요하게 되었습니다. 이러한 설정 순서 변경은 서비스 API 에 따른 데이터 초기화 자체가 사실상 지양되어야 할 기능사양이고, 사용한다고는 전제조건도 테이블이 온전히 존재한다는 상황으로 조건부가 변동된 것이 아닌가 예상됩니다. 이유를 막론하고 위 조건에서 사용하기 위해서는 다음 두개의 설정이 필요합니다.

spring:
  jpa:
    defer-datasource-initialization: true
  sql:
    init:
      mode: always

설정명을 참조하면 datasource-initialization 의 실행순서를 후순위로 연기하고, SQL 에 의한 초기화를 진행하겠다고 지정하는 것입니다. 두 가지로 나뉘어야 작동하는 것을 생각하면, SQL 방식 외에도 추가적인 주입방식이 존재하리라 예상됩니다.

data.sql > sql constraints ??? syntax error ??? > BUG ??

image

다음 에러로그를 보시면 데이터 주입에서 FK 연결이 안된다는 내용이 보입니다. 하지만 실제 원인은 다른 곳이 있었습니다.

image

우선 제가 설정한 내용입니다. # 주석을 통해서 구역을 표시하려 했습니다. 그런데 위 오류를 해결하기 위해 주석처리 제거해보니 자체를 분기로 그 다음 sql 구문이 비정상적으로 수행된다는 걸 알게 되었습니다. 상세한 이유는 모르겠지만, intelliJ 에서 지정해주는 주석인 # 이 spring 의 예약어에 맞지 않거나 문법적인 오류로 판단되는 등 예상치 못하는 문제로 비정상적으로 실행되는 것 같습니다. 해당 Bug 의 reference 는 찾지 못했고, 위 기능 자체가 실제로 dev-level 에서 특수한 경우에만 사용되므로 추가적인 조사는 중단하기로 했습니다.

  • 결론 : data.sql 사용시 주석을 자제하도록 합시다.
Clone this wiki locally