카테고리 없음

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

Lahezy 2023. 6. 15.
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

댓글