Spring Data JPA 꼭 써야할까?

allen·2022년 12월 4일
0

본인은 JPA를 깊게는 모르지만, JPA를 사용하는 개발자들에게 인지 부하를 일으키는 JPA를 살펴보려고 한다.

EntityManager

JPA는 1차 캐시라는 이름으로 엔티티매니저가 엔티티들을 자체적으로 관리한다. 엔티티매니저에 변경할 엔티티를 기록하여 flush되는 시점에 효율적인(?) 쿼리를 생산하여 한 번에 처리한다.

예측 불가능한 쿼리

분명 EntityManager에서 쿼리를 효과적으로 처리해주는 건 좋다. 하지만 이런 Lazy한 특성때문에 우리는 Service 계층의 코드를 작성하는데 쿼리를 예측할 수 없다. 그래서 개발자가 원하는 대로 비즈니스가 실행되지 않을 수 있다.

추가로 다른 프레임워크와 사용 시, JPA에서 한 작업을 flush를 해야 한다(아직 쿼리가 나가지 않았음) 이런 것도 프레임워크를 이해하지 못하면 알 수 없는 지점이다.

더티체킹으로 자연스러운 가변객체 생성

엔티티매니저가 엔티티 객체들의 스냅샷을 체크하고 있어서, flush 시점에 객체들의 상태를 비교하여 값들을 insert/update해준다.
이 부분에서 자연스럽게 엔티티는 가변객체가 된다.

LazyLoading, EagarLoading?

레이지한지, Eager하는지는 왜 알아야 할까? 이런 코드들이 엔티티클래스를 더럽히고 있다.

또 레이지로딩을 구현하려다보니 Entity클래스는 프록시기반으로 설계되어있다. 그래서 Noargument Constructor와 final class를 만들 수 없는 단점이 생긴다.

(Lazy 하게 가져와야 한다는 건 잘못된 설계로 코드를 작성한 게 아닌가? 생각이 든다.)

1:N, N:1, 양방향 매핑?

연관관계 매핑도 너무 어렵다. 일반적으로 알려진(책, 인터넷강의) 지식은 N:1를 지향한다. 도저히 안되겠으면 1:N으로 진행하라고 한다.

객체흐름관점에서는 N:1매핑은 부자연스럽다. 많은 개발자들이 N:1관계로 매핑하여 코드를 생산하고 있다.

특히 1:N 매핑을 할 때는 양방향 매핑을 진행하라고 하는데, 양방향 매핑은... 휴먼에러가 발생할 수밖에 없는 코드를 생산하게 된다.

(toString() 순환참조 관련 롬복 이슈가 있다고 하는데, 롬복 이슈가 아니라 JPA 양방향 매핑이 잘못된 거 아닌가? 싶다)

객체지향적인 코드 생산?

JPA를 쓰면서 더 객체지향 코드를 생산할 수 있다

❌ 전혀 아니다. 우리는 Spring Data JPA로 RDB에 의존적인 코드를 작성하고 있다.

지금은 아키텍처로 변화하고 있지만, 아직 도메인과 JPA 엔티티가 결합되어 RDB에 의존적인 도메인코드가 생산되고 있다.

만약 RDB에서 NoSQL로 변경하면 도메인코드를 재활용 할 수 있는가? 전혀 아니다.

결론

JPA는 처음 사용하는 개발자들에게 인지부하를 준다. 몇몇 개발자는 '너네 잘못 쓴 거다. JPA가 어려우니까 잘 알고 써야한다'라고 말한다.
하지만 내 의견은 다르다. 프레임워크가 자체적으로 잘못 만들어졌고, 어렵게 만들었다. 득도 있지만 실이 많은 것 같다.

그래서 Spring Data JDBC를 고려해봐도 좋을 것 같고, 도메인로직이 DB에 의존하지 않도록 코드를 작성해도 좋을 것 같다.

profile
개발을 즐겁게!

0개의 댓글