반응형

 

문제

  • 테스트를 실행하는 도중 아래와 같은 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available 메시지와 함께 테스트 코드가 모두 실패하였다.

 

원인

  • 나의 경우 JPA 구성을 수동으로 설정하였다. 아래 코드에서 보면 Bean의 이름은 mysqlEntityManager로 작성되어있다.
	.
	.
	.

@Bean(name = "mysqlEntityManager")
    public LocalContainerEntityManagerFactoryBean mysqlEntityManager(EntityManagerFactoryBuilder entityManagerFactoryBuilder
            , @Qualifier("mysqlDataSource") DataSource mysqlDataSource) {
        return entityManagerFactoryBuilder
                .dataSource(mysqlDataSource)
                .packages("com.projectteam.coop")
                .persistenceUnit("mysqlJpa")
                .build();
    }
    
    .
    .
    .
  • 스프링 부트의 경우 @EnableJpaRepositories 를 사용하지 않아도 기본적으로 자동 구성이 되기 때문에 별도로 작성하지 않아도 된다. (현재 나의 개발환경도 스프링 부트이기 때문에 별도의 애노테이션을 작성하지 않았다.)
  • 문제는 @EnableJpaRepositories의 속성 중에 entityManagerFactoryRef 라는 것이 있다.
    • 이 속성은 @EnableJpaRepositories 를 통해 검색된 Repository들을 생성할 때 사용할 EntityManagerFactory Bean의 이름을 지정할 수 있다.
    • 이 속성의 기본 값이 entityManagerFactory 이다.
  • 현재 찾은 Repository 들을 생성하려고하는데 entityManagerFactory 은 없고 mysqlEntityManager 빈이 등록되어있어 에러가 발생한 것으로 추측된다.

 

 

해결

  • 첫 번째 방법은 애플리케이션에 entityManagerFactoryRef 속성 값을 재정의하여 정확한 entiryManagerFactory를 사용하게 하는 것이다.
@SpringBootApplication
@ServletComponentScan(basePackages = "com.projectteam.coop.util")
@EnableJpaRepositories(entityManagerFactoryRef = "mysqlEntityManager") // entityManagerFactoryRef 값을 수동으로 구성한 entiytyManagerFactory Bean 이름으로 재설정
public class CoopApplication {
    //외부 설정파일을 이용해서 스프링 부트 구성
    public static void main(String[] args) {
        String APPLICATION_LOCATIONS = "spring.config.import="
                + "optional:../properties/local_security/coop_server_local.yml,"
                + "optional:../properties/coop_server.yml";
        new SpringApplicationBuilder(CoopApplication.class)
                .properties(APPLICATION_LOCATIONS)
                .run(args);
    }
}
  • 결과

 

  • 두 번째 방법은 수동으로 구성한 entityManagerFactory Bean의 이름을 entityManagerFactoryRef 기본 값으로 변경하는 것이다. 이 경우 첫 번째 방법에서 애플리케이션에 작성한 애노테이션(@EnableJpaRepositories) 을 지워도 된다.
	.
	.
	.

@Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mysqlEntityManager(EntityManagerFactoryBuilder entityManagerFactoryBuilder
            , @Qualifier("mysqlDataSource") DataSource mysqlDataSource) {
        return entityManagerFactoryBuilder
                .dataSource(mysqlDataSource)
                .packages("com.projectteam.coop")
                .persistenceUnit("mysqlJpa")
                .build();
    }
    
    .
    .
    .
  • 결과

 

 

  • 최종적으로 두 번째 방법을 선택했다. 이유는 스프링 부트에서 기본으로 설정된 값이 이 애노테이션 뿐만 아니라 다른 애노테이션에서도 사용되었을 가능성과 애플리케이션에 애노테이션이 추가됨으로써 코드가 점점 더 복잡해지는 상황을 생각해서 가능하면 애노테이션을 최소한으로 다는 것이 좋다고 판단했기 때문이다.

 

참고

반응형

+ Recent posts