인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

asdkfur님의 프로필 이미지
asdkfur

작성한 질문수

실전! 스프링 데이터 JPA

순수 JPA 기반 리포지토리 만들기

Spring jpa repository

해결된 질문

작성

·

534

3

안녕하세요 이번강의도 정말 잘듣고 있습니다.

다만 궁금한 점이 있다면..스프링 JpaRepository를 쓰면 jpa에 종속적인 repository가 만들어지지 않을까요? 원래 repository 패턴을 장점중 하나가 (캐쉬,api,nosql)등 구체적인  데이터 소스에 대한 의존성을 줄이기 위함이라 알고 있는데.. 실무에서는 사실상 적용하기는 개발공수에 비해 얻는 이점이 크지 않는건가요?

실무에서 그럼보통 nosql로 변경되거나 api로 변경되면(거의 없겠지만) 거의 대부분을 다시 작업하나요?

그리고 혹시 jpql사용시 join 과 fetch join의 차이점은 select 할때 받아오는 컬럼에만 차이가 있는건가요?

답변 5

4

김영한님의 프로필 이미지
김영한
지식공유자

이론적으로 좋은 아키텍처는 구현 레벌의 기술 선택을 최대한 늦추는게 좋습니다.

그래서 이런 시도는 매우 좋은 시도입니다.

저도 RDB중에서 MySQL을 사용하다가, 오라클을 사용하도록 변경했던 경험이 있는데, JPA 덕분에 정말 짧은 기간에 구현 기술을 변경할 수 있었습니다.

그런데 같은 RDB를 변경하는 것을 넘어서, RDB와 NoSQL의 페러다임 차이는 사실 너무 큽니다. 단순히 인터페이스 구현 차원을 넘어서 엔티티를 설계하는 방법부터 차이가 납니다.

특히 복잡한 실무 상황에서는 더욱 더 쉽지 않습니다. 단순히 테이블 하나 둘 정도에 비즈니스가 매우 단순하다면, 이런 스타일로 설계하는 것이 충분히 도움이 될 수 있다 생각합니다.

이런 고민이 들때 제가 드리는 실무적인 조언은 2가지 입니다. (저도 항상 이런 고민을 해서요 ㅎㅎ)

1. 인터페이스도 비용이다.

-> 추상화를 하는 것은 매우 큰 비용입니다. 추상화는 결국 생각을 2번이상 해야 하니까요. 내가 추상화 한 코드는 읽을 수 있지만 누군가가 어설프게 추상화한 코드를 보면 아주아주 화가 납니다. ㅋㅋ 그래서 이런 추상화라는 비용을 넘어설 만큼 효과가 있을 때 사용해야 합니다.

2. 이런 고민을 계속하되, 지금은 가장 단순하고 실용적인 방법을 선택해라

-> 너무 추상적인 것을 생각하다보면, 뜬구름을 잡게 되고, 결국 미래에 사용하지 않을 개발을 하게 됩니다. 오히려 가장 단순한 방법으로 실무에서 개발하고, 유지보수성을 낮추다가, 유지보수가 어려워지는 타이밍이 되면 그때 그 다음 고민을 하는 것이 더 나은 선택입니다. 예를 들어서 이 프로젝트를 RDB로 개발하는데, 미래에 너무 잘되어서 성능 때문에 Redis나 MongoDB로 전부 변경해야 하면 어떻게 하지? 사실 이런 고민을 하는 것은 좋지만, 미리 추상화를 해서 구조를 만드는 비용을 정말 들여야 하는가에 대해서는 진지한 고민이 필요합니다. 왜냐하면 그렇게 하지 않을 확율이 99%기 때문이지요.

그래도 이런 고민이 계속 쌓여야 좋은 아키텍트가 될 수 있는 것 같아요.

즐거운 하루 되세요^^

2

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. asdkfur님 열심히 달리고 계시군요^^

Q: 다만 궁금한 점이 있다면..스프링 JpaRepository를 쓰면 jpa에 종속적인 repository가 만들어지지 않을까요? 원래 repository 패턴을 장점중 하나가 (캐쉬,api,nosql)등 구체적인  데이터 소스에 대한 의존성을 줄이기 위함이라 알고 있는데.. 실무에서는 사실상 적용하기는 개발공수에 비해 얻는 이점이 크지 않는건가요?

실무에서 그럼보통 nosql로 변경되거나 api로 변경되면(거의 없겠지만) 거의 대부분을 다시 작업하나요?

-> JpaRepository를 Mongo나 다른 데이터베이스의 리포지토리로 변경해도, 대부분은 스프링 데이터 커먼의 리포지토리 인터페이스 기반의 기능을 사용하기 때문에 약간의 변경만으로 다른 기술로 쉽게 변경할 수 있습니다. 라고 말하는 것은 사실 정말 단순한 테이블 하나 둘 있을 때는 가능합니다. 결국 이론적인 내용인 것이지요. 실제로 SQL 기반의 데이터베이스와 nosql 기반의 데이터베이스 기술은 매우 다르기 때문에 많은 부분을 다시 개발해야 합니다. 이부분은 스프링 데이터를 사용하든, 하지 않든 RDB와 도큐먼트 기반의 데이터베이스의 페러다임 차이가 크기 때문에, 어쩔 수가 없습니다. 그래도 스프링 데이터가 많은 부분을 추상화해주어서, 완전히 처음부터 다른 기술로 변경하는 것 보다는 수월하게 변경할 수 있습니다.

Q: 그리고 혹시 jpql사용시 join 과 fetch join의 차이점은 select 할때 받아오는 컬럼에만 차이가 있는건가요?

-> fetch join은 연관된 객체 그래프를 한번에 같이 조회하는 기능입니다. 함께 조회하기 때문에 join도 필요하고, select절에 필드 결과에도 추가 됩니다. 반면에 Join은 연관된 객체 그래프를 한번에 조회하는 것은 아니고, 우리가 아는 단순한 join과 같습니다. fetch join을 사용하면 LAZY가 초기화 되지만, join만 해서는 LAZY가 초기화 되지 않습니다.

감사합니다^^

1

제가 하고 싶었던 질문과 이해가 잘되는 답변이었습니다.

감사합니다.

1

asdkfur님의 프로필 이미지
asdkfur
질문자

하 역시나  정말 좋은 조언 감사합니다. 저에게는 정말 단비 같은 조언 입니다.  

정말 정말 감사합니다. ㅎㅎ!!

1

asdkfur님의 프로필 이미지
asdkfur
질문자

정성스러운 답변 감사합니다. 

첫번째 질문에 추가적인 질문은 현재 서비스나 컨트롤러가 org.springframework.data.repository 패키지의 CrudRepository에 의존하는게 아닌 JpaRepository를 상속받은 memberRepository,OrderRepository에 의존하는 상황으로써 다른 no sql이나 redis 등으로 변경 되었을때 의존하고 있는 모든 서비스나 컨트롤러가 에서도 변경이 불가피해 보입니다. 그래서 혹시 아래와 같은 방법으로 구조를 잡는것은 어떤지 궁금합니다.

1. MemberRepository interface를 만들고 사용하는 측에서는 MemberReposiotry에 의존하여 향후 JpaMemberRepository class, RedisMemberRepository class 등으로 언제등지 의존성을 변경할수 있도록 합니다.

2. JpaMemberRepository class 의 내부구현은 직접 entity manager를 사용해서 구현 또는, Spring.data.jpa.repository.JpaRepository를 extends 한 또다른 인터페이스 예를들어)JpaSpringMemberRepository를 만들어 JpaMemberRepository class에서 JpaSpringRepository를 프록시처럼 감싸서 만들어서 사용합니다.

이 방법은 분명 생산성, 복잡성 측면에서 그냥 JpaRespository를 extends 해서 사용하는 것보다 안좋아 보입니다. 하지만 좀더 변경 여파를 줄일 수있는 것으로 생각되는데 실제로는 문제가 많을까요? 그리고  선생님의 말씀처럼 패러다임차이로 대부분의 변경이 일어나기 떄문에 코드 전체적인 변경이 불가피함으로 불필요한 작업일까요?

asdkfur님의 프로필 이미지
asdkfur

작성한 질문수

질문하기