본문 바로가기

JPA/JPA 소개

#02 패러다임의 불일치

Index

  • 상속
  • 연관관계
  • 객체 그래프 탐색
  • 비교
  • 정리

객체와 관계형 데이터베이스는 지향하는 목적이 서로 다르므로 둘의 기능과 표현 방법도 다르다. 이것을 둘의 페러다임 불일치 문제라고 한다. 그러므로 객체를 테이블 구조에 저장하는 데는 한계가 있다.이 한계점을 개발자가 중간에서 해결해야한다. 문제는 이런 페러다임 불일치 문제를 해결하는데 너무나 많은 시간을 소비해야 되기 때문이다. 이러한 문제점에 대해서 JPA는 해결책을 제시한다.  

상속

객체와 DB를 가장 비슷하게 설계할 수 있는 부분은 아래와 같다.

객체 : 상속

DB모델링 : 슈퍼타입 서브타입 관계

 

하지만 우리는 상속관계의 클래스마다 각각 Insert 문을 작성해야 되는 일을 지금도 하고있다. 

(나한테는 너무나 당연한 것 처럼...)

이렇게 객체 지향과 관계형 DB는 페러다임의 불일치를 가지고 있다.

 

JPA에서는 위에서 발생되는 불일치를 해결할 수 있다.  우리는 상속된 객체를 저장할 때 부모와 자식의 데이터를 각각 INSERT 문으로 작성할 필요가 없어진다. 그 모든것을 JPA가 도와주기 때문에 가능하다.

 

연관관계

객체의 연관관계 : 객체의 참조 

테이블의 연관관계 : 왜래 키를 이용해서 조인 사용

 

이렇게 다른 패러다임 불일치 문제 때문에 객체이향 모델링을 거의 포기하게 만들 정도로 극복하기 어렵다고 한다. 

그 이유는 객체 지향에서 외래키를 맴버로 두면 테이블에 INSERT할 때에는 그대로 넣으면 되기 때문에 편하지만

만약 해당 외래키역할의 멤버로 조인을 하려고 한다면??  아마 외래키와 같은 키를 찾으려고 조인하는 객체의 사이즈 만큼 반복해서 탐색을 하게 될 것이다.  그리고 그 탐색 과정도 우리가 모두 작성을 해야될 것이고... 책에서 이야기하는 부분은 이렇게 페러다임이 일치하지 않기 때문에 객체는 참조를 하는 방식으로 조인하려는 객체를 순회하는 일이 없고 바로 필요 하다면 해당 참조변수를 부르기만 하면 사용할 수 있다는 장점이 있다. 이렇게 참조가 객체지향적인 방법이라고 책에서는 이야기 하고 있다. 그렇기 때문에 객체는 참조를 통해서 관계를 맺는게 좋다라고 이야기한다. 그러나 참조를 통해서 설계를 하면 우리는 또 다른 많은 일들을 우리 스스로 해결해야 된다. 하지만 그 부분을 JPA가 알아서 작성하고 조회 또는 삽입 등을 하기 때문에 우리는 관계형DB에 상관없이 객체지향적으로 개발 할 수 있는 큰 장점을 얻을 수 있다. 

여기까지 이야기한 내용 만으로도 사실 JPA가 흥미로웠는데 저자는 다음의 문제를 해결하므로 JPA의 더욱큰 장점을 이야기 하고 있다.

 

객체 그래프 탐색

JPA 프로그래밍 책 그림 1.5 객체연관관계

위 그림처럼 객체의 연관관계를 표현 한다고 하면 우리는 서로 참조될 것으로 생각하고 객체에서 멤버를 호출하는 방식으로 아래처럼 사용할 수 있다.

Team team = member.getTeam(); 

OrderItem orderItem = member.getOrder.getOrderItem();

member.getOrder.getOrderItem().getOrderItem() ... 

 

하지만 우리가 SQL로 조회 쿼리를 작성 한다면 우리는 사용하려는 테이블을 조인해서 사용하는 멤버만 조회할 수도 있고 또는 모두 조회할 수도 있다. 이처럼 우리는 SQL에 의존적인 개발을 하고있기 때문에 객체 그래프 탐색을 할 수 없고 

우리가 사용할 객체가 있는지 확인을 해야되기 때문에 상시 SQL을 열어서 사용하려는 테이블과 멤버를 확인해야만 한다. 이 부분이 객체이향 개발자에겐 너무 큰 제약이라고 김영한님은 이야기 하고있다. 그리고 JPA는 여기서도 해결책을 제시하고 있다. 우리가 객체 그래프를 탐색하면 JPA가 설정에 따라서 적절하게 필요한 테이블을 조회해 주는 SQL을 만들고 결과를 참조값에 넣어주기 때문에 우리는 마음놓고 객체 그레프를 사용할 수 있다.

 

비교

객체지향의 비교 : 참조변수 비교 

우리가 자바에서 원시자료형을 선언하지 않고 String 이나 클래스 변수를 선언하면 해당 변수는 Heap에 생성되고 주소값을 가진다. 그렇기 때문에  같은 String 이라도 == 비교를 하면 다른값이 나올 수 있다. (내부적으로 inturn() 이라는 메소드를 사용하기 떄문에 우리는 같은 문자열에 대해서 == 비교를 하더라도 같다는 결과를 얻을 수 도있다. 하지만 이는 문자열의 값이 같다는 이야기가 아닌 다순히 Heap의 메모리 주소가 같다는 이야기다. )

위와 같은 문제로 우리는 Team1 과 Team2에 대해서 서로 다른 객체라면 같지않다는 결과가 나오게 된다. 이 부분을 방지 하기 위해서 우리는 Team1과 Team2의 인스턴스를 생성할 때 같은 인스턴스를 return한다면 Team1과 Team2는 같다라고 할 수 있다. JPA는 같은 트랜젝션일 때 같은 객체가 조회되는 것을 보장하기 때문에 우리는 신경쓰지 않고 사용해도 되는 것 같다. 하지만 분산 환경이나 트랜잭션이 다른 상황까지 고려하면 더 복잡해진다고 한다. 

이부분은 책을 진행하면서 ... 나중에... 

 

정리

객체와 DB모델링의 패러다임은 다르다.

패러다임의 불일치를 극복하기 위해서 개발자의 소비가 너무 많다.

객체지향 언어지이만 결국 데이터 중심의 모델로 변해간다.

이런 고민을 해결하기 위한 결과물이 JPA고 객체 모델링을 유지하도록 도와준다.

 

내생각

아직 공부를 얼마 안해서 정확하지 않지만 실제 내가 일하면서 사용하는 10개 이상의 테이블... 그리고 통계쿼리 등 여러가지 부분을 어떻게 JPA에서 해결할지 너무 궁금하다. 그리고 배민에서 엄청나게 복잡한 부분을 어떻게 JPA로 모두 사용했을지 너무너무나 궁금하다...   왜냐하면 현제 금융권에서 배치쿼리를 작성하고 운영하는데 엄청난 시간과 조인... 힌트등 여러가지가 필요하기 때문에 이런 부분을 어떻게 해결할지 나는 정말 너무나 궁금하다 !! 끝!! 

 

'JPA > JPA 소개' 카테고리의 다른 글

#03 JPA란 무엇인가?  (0) 2021.05.30
#01 SQL을 직접 다룰 때 발생하는 문제점  (0) 2021.05.16