🏕️ 상황
@Sql("/insert-members.sql")
@Test
void getAllMembers() {
// when
List<Member> members = memberRepository.findAll();
// then
assertThat(members.size()).isEqualTo(3);
}
- 위에 있는 코드를 실행하려면 [insert-member.sql]를 읽어와야 하는데 해당 파일을 찾을 수가 없어서 오류가 계~~~~속 발생했다.
💦 과정
이 오류를 해결하기 위해서 3시간 넘게 쓰면서 아래에 있는 방법들 + α 를 시도해보았다.
1. 혹시 모르니 설정 파일에 전체 코드에 대한 로그 레벨을 설정해 보기
2. build.gradle 파일에서 sourceSets 블록에 src/test/resources 경로 지정하기
3. sql 파일의 이름 바꾸기 / 위치 바꾸기
4. 해당 경로가 맞는지 n차 확인
5. 절대경로로 표현해 보기
6. 설정 파일에 [spring.jpa.defer-datasource-initialization: true] 넣어보기
🗝️ 해결
위에 있는 방법을 아~무리해도 같은 오류 메시지가 계속 발생했다.
가끔가다가 다른 사람들도 resource 폴더를 인식을 못하는 경우가 있다길래 Settings에 들어가서 인식 여부를 확인해 봤는데,
잘 인식하고 있었다. 그러니 더더욱 막막했다. 검색해서 나오는 건 많이 해봤기 때문이다~~
아무리 시도를 해도 달라지지 않는 걸 보면 원래부터 or 오류를 해결하는 과정에서 프로젝트에 문제가 단단히 생겼다는 판단이 들어서 새로운 프로젝트를 생성해서 다시 프로젝트를 구성했다.
그랬더니 성공....!!! (오류를 해결하면서 꼭 알아가고 싶은 궁금증이 3개 생겼다.)
💜 궁금증1 . @Sql을 사용해야 하는 이유
- 데이터베이스 초기화 및 설정:
- 테스트를 실행할 때 데이터베이스를 특정 상태로 초기화해야 하는 경우가 있습니다. @Sql을 사용하면 테스트 실행 전에 SQL 스크립트를 실행하여 데이터베이스를 초기 상태로 설정할 수 있습니다.
- 이는 특히 엔터프라이즈 애플리케이션에서 테스트 간에 데이터 일관성을 유지하는 데 유용합니다.
- 복잡한 데이터 시나리오:
- JPA를 사용하여 데이터베이스 상태를 설정하는 것은 복잡한 데이터 시나리오에서는 번거롭고 시간이 많이 걸릴 수 있습니다. 복잡한 데이터 모델이나 관계를 설정해야 하는 경우 SQL 스크립트를 사용하는 것이 더 간단하고 명확할 수 있습니다.
- @Sql을 사용하면 복잡한 데이터 시나리오를 간단한 SQL 쿼리로 설정할 수 있습니다.
- 데이터베이스 종속 테스트:
- 특정 SQL 기능이나 데이터베이스의 동작을 테스트해야 할 때 @Sql을 사용하여 직접 SQL을 실행하고 테스트할 수 있습니다. 이는 JPA가 지원하지 않는 특정 데이터베이스 기능을 테스트하는 경우 유용합니다.
- 예를 들어, 특정 데이터베이스 트리거나 스토어드 프로시저를 테스트해야 하는 경우 @Sql을 사용하여 이를 설정하고 테스트할 수 있습니다.
- 독립적이고 재현 가능한 테스트:
- 테스트는 독립적이어야 하고, 어떤 순서로 실행되든 동일한 결과를 보장해야 합니다. @Sql을 사용하면 각 테스트 전에 데이터베이스를 동일한 상태로 초기화할 수 있으므로 테스트가 독립적이고 재현 가능하게 됩니다.
- 이를 통해 테스트 간의 상호 의존성을 최소화할 수 있습니다.
- 테스트 데이터 관리의 편리성:
- @Sql 파일을 사용하면 테스트 데이터를 외부 파일로 관리할 수 있으므로, 테스트 데이터를 수정하거나 재사용하기 쉽습니다.
- 여러 테스트에서 동일한 데이터 초기화가 필요할 때, 동일한 @Sql 스크립트를 재사용할 수 있습니다.
❓데이터베이스를 초기 상태로 설정한다는 것은 ??
테스트를 실행하기 전에 데이터베이스를 특정한 상태로 만드는 것을 말합니다.
이렇게 하면 각 테스트가 동일한 시작 지점에서 시작하고, 이전 테스트가 다음 테스트에 영향을 주지 않게 됩니다.
💜 궁금증2 . sql 파일의 위치
.sql 파일은 꼭 resources 안에 있어야 한다는 사실을 알게 되었다.
Spring Boot에서는 @Sql 어노테이션을 사용하여 SQL 스크립트를 실행할 때, 해당 SQL 파일을 애플리케이션의 클래스패스(classpath)에서 찾는다. 보통 클래스패스는 src/main/resources 또는 src/test/resources디렉터리에 있는 파일들을 포함한다.
- src/main/resources: 주로 애플리케이션이 실행될 때 필요한 리소스 파일을 포함한다. 예를 들어, 프로덕션 환경에서 사용할 SQL 스크립트나 설정 파일 등이 여기에 위치한다.
- src/test/resources: 주로 테스트를 실행할 때 필요한 리소스 파일을 포함한다. 테스트용 SQL 스크립트나 테스트 설정 파일 등이 여기에 위치한다.
💜 궁금증3 . "spring.jpa.defer-datasource-initialization: true" 의 역할
문제 상황
Spring Boot 애플리케이션을 시작할 때, 보통 두 가지 일이 순서대로 일어난다.
- 데이터베이스 초기화: SQL 스크립트를 실행해서 테이블을 만들거나 데이터를 넣는다.
- JPA 초기화: JPA가 엔터티를 보고 데이터베이스 테이블을 자동으로 만든다.
문제는 이 두 가지가 잘못된 순서로 실행되면, 예를 들어 데이터베이스 초기화가 JPA 초기화보다 먼저 실행되면, 데이터베이스 테이블이 아직 없어서 오류가 날 수 있다는 점이다.
해결책
spring.jpa.defer-datasource-initialization=true 설정을 사용하면, Spring Boot는 JPA가 먼저 데이터베이스 테이블을 만든 후에 SQL 스크립트를 실행한다. 이렇게 하면 데이터베이스 테이블이 준비된 상태에서 데이터를 넣을 수 있다.
👩🏻💻느낀 점
- 오랫동안 한 가지 오류를 해결하려다 보니 그 과정에서 생기는 의문점이 많았고, 별의별 처음 알게 된 기능들이나 규칙들도 많아서 힘들지만 좋았다.
- 공부를 하면 할수록 더 모르겠는 것이 스프링의 매력이라고 생각한다ㅎㅎ 절대 쉽게 가질 수 없는 :)
- 원래도 얄팍한 실력이지만 더욱더 겸손한 마음으로 더 치열하고, 꼼꼼하게 공부하고 싶다는 생각이 들었다♥
- 그리고 프로젝트를 새로 만들어서 하는 방법이 내 생각에는 그렇게 멋진..? 방법은 아니라는 생각이 드는데... 괜찮은 방법인지 모르겠다.

'개발공부 > spring boot' 카테고리의 다른 글
🚨ERROR - [spring boot] org.springframework.beans.factory.UnsatisfiedDependencyException: (0) | 2024.05.25 |
---|---|
🚨ERROR - Exception in thread "main" org.h2.jdbc.JdbcSQLException: Database may be already in use: (0) | 2024.05.24 |
Test code - MockMvc란? (0) | 2024.05.23 |
[java] Optional - Optional의 매핑 메소드 (1) | 2023.10.24 |
spring boot - Querydsl, DSL(Domain-Specific Language)이란?? (0) | 2023.07.15 |