서론
사이드 프로젝트를 진행하면서 전체 테스트 코드를 실행시켰더니 다음과 같은 예외가 발생하였습니다.
💡 Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'jpaAuditingHandler' defined in null: Cannot register bean definition...
멀쩡하게 돌아가던 테스트가 안되니 식은 땀이 났고, 문제를 찾아보니 테스트 코드에 @EnableJpaAuditing를 붙여 발생한 해프닝이였습니다... BeanDefinitionOverrideException은 동일한 이름의 Bean이 여러 번 등록되려고 할 때 발생됩니다.
문득 문제 원인에 대해 구체적으로 알고 싶어 포스트를 정리하게 되었습니다.
문제의 원인
@EnableJpaAuditing은 JPA Auditing 기능을 활성화하기 위해 사용됩니다. 이 기능을 활성화하면 엔티티가 생성되거나 수정될 때 자동으로 시간과 사용자를 기록하는 등의 작업을 할 수 있습니다.
문제는 @EnableJpaAuditing이 애플리케이션의 main 클래스나 별도의 설정 클래스뿐만 아니라 테스트 컨텍스트에서도 중복으로 등록될 때 발생합니다. Spring Boot는 애플리케이션 실행 시와 테스트 실행 시 각각의 애플리케이션 컨텍스트를 생성합니다. 이 과정에서 두 개의 @EnableJpaAuditing이 발견되면, Spring은 2번 JpaAuditingHandler를 생성하려고 시도하며, 이로 인해 Bean 중복 등록으로 충돌이 발생합니다.
이러한 문제는 특히 @SpringBootTest를 사용할 때 발생할 가능성이 큽니다. @SpringBootTest는 기본적으로 전체 애플리케이션 컨텍스트를 로드하기 때문에, @EnableJpaAuditing이 설정된 클래스가 이미 로드된 상태에서 또 다른 @EnableJpaAuditing이 포함된 설정이 테스트 컨텍스트에 포함되면서 충돌이 발생할 수 있습니다.
해결 방법
해결 방법은 테스트 코드 내 문제 부분의 코드(@EnableJpaAuditing)를 지우면 됩니다.
만약 테스트 클래스에 조건부로 설정하고 싶다면 어떻게 해야할까요?
테스트에 필요한 설정을 별도로 적용하고 싶다면, @TestConfiguration을 사용하여 필요한 설정을 조건적으로 추가하는 방법이 있습니다. 그러나, @EnableJpaAuditing을 테스트에 직접 사용하는 것을 권장하지는 않습니다.
@TestConfiguration
static class TestConfig {
@Bean
@ConditionalOnMissingBean
public AuditingHandler jpaAuditingHandler() {
return new AuditingHandler();
}
}
요약
테스트 클래스에서 @EnableJpaAuditing을 사용하는 경우, JpaAuditingHandler Bean이 중복 등록되어 BeanDefinitionOverrideException이 발생할 수 있습니다. 해결 방법은 테스트 클래스에서 @EnableJpaAuditing을 제거하면 됩니다. 또한 애플리케이션 컨텍스트에서 자동으로 설정된 JPA Auditing을 사용하는 것을 권장하며, 테스트 컨텍스트에 별도 설정은 권장되지 않습니다.
'Project > Trouble Shooting' 카테고리의 다른 글
warning: unknown enum constant When.MAYBE (0) | 2024.08.18 |
---|---|
Spring Security 무한 리다이렉트 문제 (0) | 2024.03.06 |