본문 바로가기

카테고리 없음

[JPA] hibernate.ddl-auto 설정

숙박 예약 프로젝트를 진행하면서 숙소 관련 부분에서 Repository 테스트를 작성했다.

@DataJpaTest
@ActiveProfiles("test")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class AccommodationRepositoryTest {

    @Autowired
    private AccommodationRepository accommodationRepository;

    private Accommodation accommodation;

    @Test
    @DisplayName("카테고리를 통한 숙소 데이터 찾기")
    void findByCategory_ShouldReturnAccommodations() {
        // Given
        accommodation = Accommodation.builder()
            .category("호텔")
            .build();

        accommodationRepository.save(accommodation);

        // When
        List<Accommodation> result = accommodationRepository.findByCategory("호텔");

        // Then
        assertFalse(result.isEmpty());
        assertEquals("호텔", result.get(0).getCategory());
    }
}

 

 

이때 application-test.yaml에서 ddl-auto를 create-drop으로 설정했더니 테스트는 통과했지만 아래와 같은 메세지들이 출력되었다.

(실제로는 더 많은 테이블에 대해서 동일한 메세지들이 출력되었다)

 

무슨 메세지인가 하고 보니 테이블이 존재하지 않아서 외래 키가 삭제되지 않았다는 뜻이었다.

 

먼저 ddl-auto 옵션들을 살펴보자.

  • create: 기존 테이블 삭제 후 다시 생성 + 닫을 때 삭제하지 않는다.
  • create-drop: create와 같으나 종료시점에 테이블 DROP
  • update: Hibernate는 주어진 엔티티 구조에 따라서 데이터베이스를 변경한다.
  • validate: 엔티티와 테이블이 정상 매핑되었는지만 확인
  • none: 어떠한 변화도 주지 않는다. mysql에서 default이다.

여기서 필자가 적용했던 create-drop 은 실행할 때마다 테이블을 생성하고 삭제하는 것이다. 그런데 중요한 점은 생성 전에 엔티티와 관련된 기존 테이블을 먼저 삭제한다는 것이다. 

테스트 실행 ㅡ> 기존의 외래 키 삭제 ㅡ>  기존의 테이블 제거 
ㅡ> 새로운 테이블 생성 ㅡ> 새로운 외래 키 생성 
ㅡ> 테스트 종료 ㅡ> 생성한 외래 키 삭제 ㅡ>  생성한 테이블 제거

 

 

Hibernate는 가장 먼저 엔티티 구조를 참고해서 외래 키를 삭제한 후 테이블을 삭제하는데, 기존의 테이블이 존재하지 않을 때 외래 키를 삭제하려다보니 오류가 발생한 것이다.

 

그런데 기존 테이블이 존재하지 않다보니 외래 키도 존재하지 않고, 따라서 외래 키 삭제 오류 이슈가 발생해도 문제 없이 테스트 실행은 되는 오류 아닌 오류인 것이다.

 

이왕이면 해결하는게 좋을 이 오류 아닌 오류를 해결해보자.

방법은 간단하다. ddl-auto 설정을 update나 update 후 validate를 사용하여 테이블 구조를 유지하면서 초기 삭제를 하지 않게 하는 것이다.

이렇게 하면 존재하지 않는 기존 테이블과 외래 키에 접근하지 않기 때문에 오류가 발생하지 않는다.

 

번외로 이후 한번은 create-drop으로 설정 후 실행하면 메세지가 뜨지 않는다. 왜냐하면 update의 효과로 기존 테이블이 존재하기 때문이다.