ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA 다른 모듈에서 ENTITY 스캔하기
    spring/JPA 2021. 4. 29. 08:59

    배경

    마이크로 서비스를 구축하면서 서비스와 서비스를 연결할 때 공통으로 필요한 코드는 모듈로 분리했다. 일명 라이브러리모듈로서 main은 없고 적절히 import만 할 수 있게 만든 것이다. 이러면 공통적으로 사용하는 코드를 한 모듈에서 관리하니 유지보수성이 크게 올라간다.

     

    그렇다면 어떤 코드가 이 라이브러리모듈에 들어가야 할까? 아직 노하우가 많지 않아 정확한 판단을 하기는 어렵지만 작은 경험으로 추측해보았다. 먼저 DTO 같은 경우 큰 논란 없이 라이브러리모듈에 들어가도 될 것 같다. 다음으로 @Entity애노테이션이 붙은 도메인클래스를 생각해봤다. 한 서비스에서 하나의 도메인만 다루더라도 연관관계가 얽혀 있다면 다른 도메인이 필요할 것이다. 결국 완성된 데이터는 한 서비스에서 조립되어 전달되니 도메인도 라이브러리모듈에 넣어보면 좋을 것 같다.

     

    현재 프로젝트의 경우 레파지토리는 서비스모듈에, 엔티티는 라이브러리모듈에 넣어뒀다. 그리고 간단히 엔티티를 저장하는 테스트 코드를 작성했다.

     

     

    문제의 시작

    라이브러리모듈인 commonlibrary에 있는 Member클래스가 관리받는 타입이 아니라는 오류다. 이 오류 때문에 MemberRepository를 생성할 때 오류가 생겨 문제가 생긴 것이다.

     

     

    외부에서 엔티티 당겨오기

    문제는 외부 모듈에 있는 클래스는 JPA의 스캔 대상이 아니라는 점이다. 이를 해결하기 위해 제공하는 애노테이션이 @EntityScan이다!

    위와 같이 스캔하고 싶은 패키지를 입력한 애노테이션을 붙여주자. 이후 테스트 또한 진행해보자.

    테스트를 무사히 성공한 걸 확인 할 수 있다.

     

     

    참고

    프로젝트에서는 아래와 같이 설정을 추가해줬다.

    @Configuration을 이용해 빈으로 등록을 해줘야 정상적으로 동작하는 걸 확인할 수 있었다. 다만, 테스트의 @DataJpaTest는 이 설정을 무시하니 테스트 시에 따로 애노테이션을 붙여줘야 한다.

    왜 그럴까 추측해보면 @EntityScan은 JPA에서 지원하는 애노테이션이 아닌 스프링이 지원하는 애노테이션이다. 이 사실로 미루어보아 빈으로 등록하는 건 당연하고 jpa관련 설정만 테스트해주는 @DataJpaTest가 @EntityScan을 인식하지 않는 것도 크게 이상할 게 없다. 다만, 어떻게 JPA가 해야할 일을 스프링의 애노테이션이 해주는지는 정말 놀랍고 신기할 따름이다.

     

    똑같은 논리로 JPA의 레파지토리를 추가하고 싶을 땐 @EnableJpaRepositories를 사용하자 ^^

     

     

     

    댓글

Designed by Tistory.