카테고리 없음

스프링 부트, 임시 데이터 넣는 방법(데이터가 들어가지 않는 오류)

Lahezy 2023. 6. 15. 17:25
728x90

결론

임시 데이터를 넣는 yml 코드입니다. 

현재 프로젝트 세팅은 Java 17버전에 Springboot 3.1.0을 사용합니다.

resources폴더 밑에 data.sql파일을 넣었습니다.

spring:
  datasource:
    url: jdbc:sqlite:db.sqlite
    driver-class-name: org.sqlite.JDBC
  jpa:
    hibernate:
      ddl-auto: create
    show-sql: true
    database-platform: org.hibernate.community.dialect.SQLiteDialect
    defer-datasource-initialization: true # 데이터 베이스 초기화 시점을 지연시킨다.
  sql: #해당 부분을 추가합니다
    init :
      mode: always

 

 

문제상황

spring:
  datasource:
    url: jdbc:sqlite:db.sqlite
    driver-class-name: org.sqlite.JDBC
  jpa:
    hibernate:
      ddl-auto: create
    show-sql: true
    database-platform: org.hibernate.community.dialect.SQLiteDialect
  sql:
    init :
      mode: always
      data-locations: classpath:data.sql

ERROR : Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [data.sql]:

임시데이터를 넣어 테스트를 진행하려 springboot의 yml파일에 data.sql파일을 실행하도록 했는데 쿼리가 들어가지 않는 문제가 있었습니다. 

 

도전

더보기

생성당시에 jpa에 의해 테이블이 생성되지 않아 scheme없어서 그런가 하고 scheme를 넣었보았습니다.

spring:
#위의 코드 생략
  sql:
    init :
      mode: always
      schema-locations: classpath:scheme.sql
      data-locations: classpath:data.sql

테이블이 생성되었지만 데이터는 여전히 삽입되지 않는 문제가 있었습니다. 

 

 

 

해결

data.sql 쿼리가 동작하지 않는 문제를 인터넷에 검색해 보았습니다. 

 

다른 개발자님들의 글을 보니 spring.jpa.defer-datasource-initialization: true을 사용하여 해결하는 것 같았습니다.

추가해서 도전해 보았습니다.

 

spring:
  datasource:
    url: jdbc:sqlite:db.sqlite
    driver-class-name: org.sqlite.JDBC
  jpa:
    hibernate:
      ddl-auto: create
    show-sql: true
    database-platform: org.hibernate.community.dialect.SQLiteDialect
    defer-datasource-initialization: true # 데이터 베이스 초기화 시점을 지연시킨다.
  sql: #데이터 베이스 초기설정
    init :
      mode: always
      schema-locations: classpath:scheme.sql
      data-locations: classpath:data.sql

logging:
  level:
    web: debug

데이터가 들어가는 걸 확인할 수 있었습니다.

 

spring.jpa.defer-datasource-initialization: true는 Hibernate 초기화 전에 쿼리를 실행해서 데이터를 생성할 수 있습니다.

 

WHY?

 

공식 문서 참고

https://docs.spring.io/spring-boot/docs/3.1.0/reference/htmlsingle/#howto.data-initialization.using-basic-sql-scripts

 

 

번역기를 돌려봤습니다🥲(2번째 문단입니다)

 

 

스크립트 기반 DataSource 초기화는 기본적으로 JPA EntityManagerFactory 빈이 생성되기 전에 수행됩니다. schema.sql을 사용하여 JPA 관리 엔티티에 대한 스키마를 생성하고 data.sql을 사용하여 이를 채울 수 있습니다. 여러 데이터 소스 초기화 기술을 사용하는 것은 권장하지 않지만, 스크립트 기반 데이터 소스 초기화가 최대 절전 모드에서 수행한 스키마 생성을 기반으로 구축될 수 있도록 하려면 spring.jpa.defer-datasource-initialization을 true로 설정하세요. 이렇게 하면 데이터 소스 초기화가 EntityManagerFactory 빈이 생성되고 초기화될 때까지 지연됩니다. 그런 다음 schema.sql을 사용하여 Hibernate에서 수행한 스키마 생성에 추가하고 data.sql을 사용하여 이를 채울 수 있습니다.

 

번역을 해석해 보자면 기본적으로 Spring Boot는 JPA EntityManagerFactory 빈이 생성된 이전에 데이터베이스 초기화를 수행합니다. 하지만 만약 spring.jpa.defer-datasource-initialization 속성을 true로 설정하면 데이터 소스 초기화가 EntityManagerFactory 빈 생성 이후에 실행되어 만약 하이버네이트 초기화로 생성된 스키마를 수정하거나, 데이터를 채우고 싶다면 spring.jpa.defer-datasource-initialization을 true로 주어야 한다고 합니다.

 

 

따라서 ddl-auto: create와 sql.data.init, data.sql을 함께 사용하면 Hibernate가 테이블을 생성한 후에 초기 데이터를 데이터베이스에 삽입할 수 있습니다. 이를 통해 애플리케이션을 시작할 시에  초기 데이터를 쉽게 넣을 수 있습니다.

 

 

 

 

 

참고

https://fftl.tistory.com/15

https://devvkkid.tistory.com/262

https://docs.spring.io/spring-boot/docs/3.1.0/reference/htmlsingle/#howto.data-initialization.using-basic-sql-scripts

 

 

728x90