[Side-story] : Spring-data-jpa 문서가 바뀌게 된 계?기

청주는사과아님·2024년 12월 27일
0

side-story

목록 보기
4/7

안녕하세요. 아직도 취준중인 백수, 청주는사과아님 입니다.

이전 포스팅에서 Spring-data-jpa 의 Non-bean instance loaded to context 에러 를 발견해 기록 했었는데요.
이제 시간이 지나 어느정도 변경점이 완료된 것 같아 유지보수 포스팅(?) 을 작성해 보고자 합니다.


I. 에러 다시보기

이전에 발견했던 에러를 간단히 다시 회고시키겠습니다.

에러는 아래와 같은 상황에서 일어났습니다.

interface SomeJpaInterface extends JpaRepository< ... > { /* ... */ }

// 그냥 이름이 (SomeJpaInterface) + (Impl) 일 뿐인
// Spring 과 아무런 관련이 없는 클래스
class SomeJpaInterfaceImpl {
	// this is just a random instance
    // so it should NOT be loaded to spring context
}

위처럼 JPA 인터페이스의 이름이 SomeJpaInterface 이고, Spring 과 관련 없는 SomeJpaInterfaceImpl 가 존재할 때, 이 클래스가 Spring Context 에 적재되는 에러였습니다.

저번 포스팅에서는 위 에러를 발견 후, 공식 github 에 물어 답변을 기다리던 상태였습니다.


II. Spring-data-jpa 형님들의 답변

issue 를 올리고 다음날 Spring-data-jpa 형님의 댓글이 달렸습니다.

형님의 답변에 의하면 Custom Repository 자체는 1.x 버전대에 만들어져 (인터페이스 이름) + Impl 인 이름 만으로 Custom Repository 를 선언하였다고 합니다.

즉, 지금은 [1] 처럼 사용하라 문서에 나와있지만 옛날에는 [2] 방식 이었다는 것이지요.

// [1] : 지금은 spring-data-jpa 3.x 버전대
// CustomRepository 를 extends 해서 **CustomRepository 를 사용함을 명시**
interface MyJpa extends JpaRepository< ... >, CustomRepository {/* ... */}

interface CustomRepository {
	/* ... Custom query methods ... */
}
class CustomRepositoryImpl implements CustomRepository {
	/* ... Custom query method implements ... */
}


// [2] : 옛날 옛적 호랑이 담배피던 1.x 시절
// 우리 에러 났었던 예시랑 동일
interface MyJpa extends JpaRepository< ... > {/* ... */}

class MyJpaImpl {
	// this were `Custom Repository` on Spring-data-jpa 1.x
}

그래서 형님은 1.x 버전대의 코드 때문에 위 에러가 발생한 것이라 의심하였고, 몇번의 추가적인 대화 끝에 이에 착수하겠다 하였습니다.


III. Spring-data-jpaCustom Repository Implementations 문서

그러부터 몇일이 지나 확인해보니 이전 올렸던 issuespring-data-commons 로 옮겨졌고, 관련된 pull request 가 만들어졌습니다.

한번 pr 변경점을 확인해보니 Custom Repository Implementations 문서가 변경되고 있었습니다.

위 내용을 각각 정리하면 다음과 같습니다.

Note

Custom Repository 를 만들 때 Impl 접미사를 붙이십시오.
이 때 @Enable<StoreModule>Repositories(repositoryImplementationPostfix = ...) 를 통해 Impl 대신 다른 접미사를 사용할 수 있습니다.

Warning

역사적(?) 으로 Custom Repository 구현체 는 아래와 같은 특정 네이밍 패턴 에 기반해 탐색됩니다.

interface UserRepositoryCustom {
  public void someCustomMethod(User user);
}

class UserRepositoryImpl implements UserRepositoryCustom {

  public void someCustomMethod(User user) {
    // Your custom implementation
  }
}

이는 Custom Repository 마다 단 하나 의 구현체만 가능토록하기 위한 의도입니다.

즉, Custom Repository 인터페이스동일한 패키지에 존재 하고 (인터페이스 이름) + 접미사 인 구현체는 Custom Repository 구현체 로 간주 되며, 이는 의도치 않은 행동을 야기할 수 있습니다.

때문에 우리는 "이름에 기반한 단일 Custom Repository 구현체 방식(?)" (single-custom implementation naming)만료를 고려중이며, 이러한 사용 방식 (pattern) 을 권장하지 않습니다.
대신 "fragment 에 기반한 프로그래밍 모델(???)" (fragment-based programming model) 로 이주하십시오.

single-custom implementation naming, fragment-based programming model 이 번역이 올바른지는 모르겠지만, 어찌되었든 이름에 기반한 Custom Repository 방식을 deprecated 하려는 것 처럼 보입니다.


IV. 후?기

현재 앞서 보여드린 문서 변경점 은 실제 공식 문서에도 적용되었습니다.

사실 포스팅으로 정리하기 전 까지만 해도 문서만 바꿔두고 안고친다 는 줄 알았는데, deprecated 시키려 하는 걸 보니 언젠가 라이브러리에 위 에러가 고쳐질 수도 있을 것 같다는 생각이 드네요.

이 에러를 물어보면서도 내가 그냥 멍청한게 아닐까, 진짜 물어보는게 맞나 등 참 많이 고민했었는데, 실제로 이렇게 답변 받고 확인을 받으니 시원하네요.
역시 모를땐 그냥 물어보는게 가장 빠르고 확실한 것 같습니다.

profile
나 같은게... 취준?!

0개의 댓글