TDD에서 DataIntegrityViolationException, ConstraintViolationException 예외 발생

LeeKyoungChang·2023년 5월 14일
0
post-thumbnail

현재 상황 service를 기반으로 TDD를 만들다,

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

이와 같은 오류가 발생했다.

 

📖 A. 이유가 뭘까..?

chatGPT에게 물어본 결과

이 오류는 데이터 무결성 위반(Data Integrity Violation)으로 인해 발생한 것으로 보입니다. 데이터 무결성은 데이터베이스에서 데이터의 정확성과 일관성을 유지하기 위해 적용되는 규칙입니다.

오류 메시지를 자세히 살펴보면 "could not execute statement"와 "constraint [null]"이라는 구문이 있습니다. 이는 실행할 수 없는 SQL 문과 null인 제약 조건(constraint)이 있다는 것을 나타냅니다. 또한, "nested exception is org.hibernate.exception.ConstraintViolationException"이라는 구문은 Hibernate에서 제약 조건 위반 예외(ConstraintViolationException)가 발생했음을 나타냅니다.

일반적으로 이 오류는 다음과 같은 상황에서 발생할 수 있습니다:

1.  데이터베이스 테이블에 설정된 제약 조건을 위반하는 데이터를 삽입하려고 시도한 경우.
2.  외래 키(Foreign Key) 관계를 가진 테이블에서 레코드를 삭제하려고 시도했지만, 해당 외래 키를 참조하는 다른 테이블에 데이터가 남아있어 제약 조건을 위반하는 경우.

이러한 경우에는 데이터베이스 스키마와 애플리케이션의 데이터 접근 계층(DAO, Data Access Object) 코드를 검토해야 합니다. 특히, 데이터를 삽입, 수정 또는 삭제할 때 제약 조건을 확인하고, 해당 조건을 위반하는 경우 예외 처리를 해야 합니다. Hibernate를 사용하는 경우에는 관련된 매핑 및 제약 조건 설정을 확인해야 할 수도 있습니다.

더 구체적인 도움을 위해서는 더 많은 오류 정보 및 관련 코드를 제공해주시면 좋을 것 같습니다.

라고 해서, 현재 나의 환경에서 이와 관련 설정을 했는지 생각해봤다!

 

스크린샷 2023-05-14 오후 7 18 41

@AfterEach에서 Repository deleteAll() 을 호출하고 있다.

나의 TestCode

@Test  
@DisplayName("현재 나의 위치를 통한 시설 조회")  
fun getCurrentLocation(){  
    // given  
    val currentLocation = FloorsCurrentLocationRequestDto(0.0, 0.0, -10.0)  
  
    // when  
    val resultCurrentLocation = floorsService.getCurrentLocation(currentLocation)  
  
    // then  
    assertThat(resultCurrentLocation).isEqualTo("4층 대강의실 안")  
}
  • 나 같은 경우 getCurrentLocation Service에 구현한 함수를 호출하는데 이때, Repository을 호출한다.
  • 따로 TDD에서 Repository를 직접적으로 사용하지도 않는데, deleteAll()을 호출하고 있다.

 

 

📖 B. 해결책

Test에서 DB를 직접적으로 호출 및 사용하는 경우 DataIntegrityViolationException, ConstraintViolationException 예외가 발생할 수 있다. (개인적인 생각이다.)

그래서, 따로 Test에서 Repository를 호출하지 않는 이상 삭제, 수정을 하면 안되는 것 같다. (Service에 구현된 메서드를 호출하는 경우, Repository에 구현된 메서드를 호출하지 않아도 된다.)

deleteAll 주석 처리하니 성공적으로 실행이 된다!

 

 

profile
"야, (오류 만났어?) 너두 (해결) 할 수 있어"

0개의 댓글