본문 바로가기

개발/Spring&JPA

[JPA] Spring Data JPA의 DB 초기화

반응형

안녕하세요 백엔드 개발자 제임스입니다.😎

 

서론


최근 우리 팀은 구현 단계에 돌입했습니다. 이에 따라 백엔드 팀도 도메인 별로 역할을 나누어 기능을 구현하고 있죠. 하지만 점점 도메인 수가 증가하면서 테스트에 어려움을 겪고 있습니다. 가령 포스트맨으로 직접 데이터를 넣으며 테스트를 하려고 해 해도 시간이 오래 걸리죠. 물론 가장 좋은 방법은 테스트 코드를 작성하는 것입니다. 하지만 우리 팀은 아직 테스트 코드를 작성하는 것이 미숙합니다. 그래서 오늘 해결책이 될 수 있는 방법을 소개하려고 합니다.

제시하는 방법은 프로그램을 시작할 때 DB에 초기 데이터를 자동으로 저장시키는 방법입니다. 이제 자세하게 알아보도록 하겠습니다.

 

초기 데이터 저장


목표 : 프로그램 실행 시 DB에 초기 데이터 자동 저장

1) yml 설정

spring.sql.init.data-locations: classpath*:db/h2/data.sql
초기 데이터의 sql 명령문이 작성된 파일 경로를 지정합니다. 위 코드에서 db/h2는 data.sql파일까지의 경로를 나타냅니다.

spring.jpa.defer-datasource-initialization : true
가장 중요한 부분입니다. 해당 설정이 없으면 아래와 같은 오류가 발생합니다.

[에러-BeanCreationException.ScriptStatementFailedException]
: [defer-datasource-initialization : true] 설정을 하지 않고 실행할 시 발생되는 에러입니다.
해당 에러가 발생되는 이유는 jpa가 테이블을 생성하기 전에, data.sql의 sql 명령어가 실행되려고 했기 때문입니다. 이에 대해 자세하게 알아보겠습니다. 해당 에러는 스프링 부트 2.4 버전에서는 발생되지 않았습니다. 하지만 2.5 버전부터 발생되는 것을 볼 수 있습니다. 

 스프링 부트 2.5의 릴리즈 노트를 자세히 알아보니, SQL Script DataSource Initialization의 기능이 변경되었다는 것을 알 수 있었습니다. 그리고 초기 데이터를 저장하고 싶으면  spring.jpa.defer-datasource-initialization 의 값을 true로 설정하라고 나왔습니다.

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.

 

2) resources에 디렉토리와 data.sql 파일 생성

yml에 설정한대로 resources > db > h2 경로 아래 data.sql 파일을 생성합니다.

 

3) SQL 명령어 작성

저는 초기에 제품과 채식 유형의 데이터를 저장해주었습니다.

 

이제 프로그램을 실행하면 DB에 초기 데이터가 저장되는 것을 볼 수 있습니다.

 

Spring data JPA의 DB 초기화 전략


자세하게는 Hibernate 전략이라고 할 수 있습니다.

위 이미지와 같이 ddl-auto 를 많이 봤을 것입니다. 이는 DB 초기화 전략 옵션을 설정하는 명령어입니다. 그리고 아래와 같은 값들을 갖습니다.

  • none : DDL 핸들링 작업을 수행하지 않음
  • create : 기존에 존재하는 스키마를 삭제하고 새로 생성
  • create-drop : 스키마를 생성하고 애플리케이션이 종료될 때 삭제
  • update : 기존의 스키마를 유지하며 JPA에 의해 변경된 부분만 추가
  • validate : 엔티티와 테이블이 정상적으로 매핑되어있는지만 검증

운영 서버에서는 create, create-drop, update를 사용하지 않습니다. 이렇듯 옵션은 상황마다 차이를 갖습니다.

  • 개발 초기 단계 : create / update
  • 테스트 서버 : update / validate
  • 스테이징과 운영 서버 : validate / none

몇 가지를 더 조사해본 결과, 실무에서는 ddl-auto를 통해 스키마를 자동으로 생성하지 않는다고 합니다. validate로 두고 검증만 할 뿐, 스키마는 직접 쿼리를 작성하여 생성한다고 합니다.

반응형