-
JPA 애플리케이션 데이터베이스 초기화Spring Boot/JPA 2023. 9. 17. 18:16
- 애플리케이션의 TestCode를 작성하려고 하면, 테스트를 위한 초기 데이터 (test fixture)가 필요하다.
- 당연히 H2 같은 in-memory DB로 테스트가 될 것을 기대하고 BeforeAll, AfterAll로 Setting하는 것으로 기대했지만,
- 현실은 build할때 실제 DB가 붙어서 동작하고 있었다. 어떻게 하면 Test Fixture를 분리 고립시킬 수 있을까?
- 지금까지 결론은 build 환경에서 DB 환경을 구성하고 @Sql로 관리하는 것이 가장 조작하기 쉬운 방법으로 보인다.
SpringBoot에서 제공하는 데이터베이스 초기화
- Spring boot에서는 데이터베이스 변경에 대한 관리 방법을 제공한다.
- default 설정은 package에 entity를 감지하여 각각의 테이블을 자동 생성한다.
- 데이터베이스를 초기화 하는 방법은 다양한 방법이 있다. 꼭 하나만 선택하여 사용하는 것을 추천한다.
1. JPA를 사용하여 Database를 초기화하는 방법
- 프로젝트를 시작할때 JPA가 DDL generation 기능을 제공한다.
- Entity를 작성하고 애플리케이션을 실행하면 빈 테이블이 생성된다.
spring.jpa.generate-ddl=true # vendor 독립적이고 on/off 할 수 있다
2. Hibernate를 사용하여 Database를 초기화하는 방법
spring.jpa.hibernate.ddl-auto=create # Hibernate에서 제공하는 기능 # none, validate, update, create, create-drop
3. SQL Scripts를 사용하여 Database를 초기화하는 방법
- SpringBoot가 자동으로 optional:classpath*:schema.sql 경로에 schema 파일을 감지하여 자동으로 실행
- optional:classpath*:data.sql 경로에서 SQL 파일을 감지하여 실행
spring.sql.init.mode=always # 사용하기 위해 외부환경 변수 선언, 사용 안하려면 never
- Hibernate EntityManagerFactory가 빈으로 등록되고 SQL이 실행될 수 있게 하는 역할
spring.jpa.defer-datasource-initialization=true
- schema.sql, data.sql 대신에 Flyway 또는 Liquibase 같은 Tool을 사용하는 방법도 있다.
4. @Sql, @SqlGroup, @SqlConfig
- 테스트에 사용할 수 있는 SQL문
@Sql({"/employees_schema.sql", "/import_employees.sql"}) public class SpringBootInitialLoadIntegrationTest { @Autowired private EmployeeRepository employeeRepository; @Test public void testLoadDataForTestClass() { assertEquals(3, employeeRepository.findAll().size()); } } @Test @Sql(scripts = {"/import_senior_employees.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = TransactionMode.ISOLATED)) public void testLoadDataForTestCase() { assertEquals(5, employeeRepository.findAll().size()); } @SqlGroup({ @Sql(scripts = "/employees_schema.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)), @Sql("/import_employees.sql")}) public class SpringBootSqlGroupAnnotationIntegrationTest { @Autowired private EmployeeRepository employeeRepository; @Test public void testLoadDataForTestCase() { assertEquals(3, employeeRepository.findAll().size()); } }
참고 :
반응형'Spring Boot > JPA' 카테고리의 다른 글
QueryDsl projections 자바 Record에 적용하기 (1) 2024.04.23 JPA 주의점 (1) - OSIV false 설정 (open-in-view) (0) 2024.04.19 [JPA] 간단하게 OneToMany 데이터 API 구현하기 - @Embeddable, @Embedded, @ElementCollection 활용하기 (1) 2023.10.15 [JPA] Repository단에 Transactional을 선언하는 이유 (0) 2023.10.05 Spring boot JPA/하이버네이트? (0) 2022.01.04