[JPA] 자바 ORM 표준 JPA 프로그래밍(기본편) 6 - 값 타입

유승선 ·2022년 11월 14일
0
post-thumbnail

비교적 가벼운 내용의 주제였다. 그렇지만 자바라는 언어에 대한 기본기가 탄탄했다면은 이해하기 훨씬 쉬웠을 주제라고 생각하고 내심 스스로 가지고 있었던 궁금증을 해소 해주었다.

임베디드 타입

위와 같은 멤버 엔티티를 생성한다고 가정해보겠다. id 와 name 은 필수적으로 가지고 있어야하는 부분이지만 startDate, endDate, city, street, zipcode는 조금 지저분해 보인다.

멤버 엔티티와 비슷한 다른 엔티티를 만들때도 저 부분을 전부 하나하나 적어주는것은 상당한 일이고 아래와 같이 줄이는게 조금 더 객체 지향적으로 느껴질 것이다.

멤버 객체 안에 있었던 startDate..zipcode 등등을 workPeriod 그리고 homeAddress 객체로 한번에 줄인 결과 조금 더 객체 지향적인 설계가 눈에 보이고 훨씬 간편해보인다.

이렇게 필요한 정보를 다른 클래스 안에 담는것을 임베디드 타입 클래스라고 하고 사용법은 아래와 같다.

@Embeddable이나 @Embedded는 임베디드 클래스 객체 혹은 변수 하나에만 달아도 된다던데 두개 같이 해주는게 뭔가 깔끔해보였다.

역시 장점으로는 재사용과 높은 응집도가 있었고 무엇보다 임베디드 타입 클래스 안에서 의미 있는 메소드를 추가적으로 만들수 있단것도 좋은거같다.

추가적으로, 임베디드 타입을 포함한 모든 값 타입은 엔티티가 생명주기를 담당한다 (엔티티 삭제 = 임베디드 타입 클래스 삭제)


임베디드 타입과 테이블 매핑

개인적으로 헷갈리는 부분도 많았지만 깔끔히 정리해준 부분같다. 임베디드 타입이 멤버 엔티티 안에 있다고 해도 달라지는건 없다. DB 입장에서는 똑같이 컬럼이 만들어지고 회원테이블을 사용할 수 있다. 다만 임베디드 클래스에 사용으로 객체 지향적인 설계가 더 이루어질 수 있다.

많이 쓰이지는 않을거 같지만 혹여나 임베디드 타입 클래스의 이름이 같다면은 위에 어노테이션을 사용해서 구분 가능하다.


값 타입과 불변 객체

임베디드 타입은 많은 장점을 가지고 있지만 역시 조심해야 되는 부분도 존재한다. 임베디드 타입은 엄연한 객체를 넣는거기 때문에 여러 엔티티에서 공유되서 사용될 가능성이 높다. 그렇지만 이건 굉장히 큰 위험을 주는데, 객체가 공유되고 특정 임베디드 클래스를 수정하게 된다면은 그 타입을 공유받고 있는 다른 멤버 클래스들이 전부 수정된 임베디드 타입 클래스를 가진다는 것이다.

(OldCity -> NewCity 로 변경시에 회원1, 회원2 모두 newCity 값의 주소를 가지게 된다)

놀랍게도 존재하는 많은 솔루션 중에 가장 간단하고 명확한거는 임베디드 타입 객체를 공유하지말고 각 회원마다 새로운 임베디드 타입 클래스를 생성해서 저장하라는 것이다.

(회원1 -> new Address(oldCity...), 회원2 -> newAddress(newCity..))

객체를 공유 받는다는것은 위와 같은 한계가 있다. 앞서 얘기했듯이 A와 B가 전부 같은 참조값을 가지고 있기 때문에 하나가 바뀌면 둘이 바뀐다.

불변 객체로 만들기 위해서 강의에서 제공한 솔루션은 아예 임베디드 타입같은 경우 세터를 없애자는 솔루션이다!


값 타입 컬렉션

이런 고민을 했다. 1회차에 강의를 들었을때는 컬렉션 객체를 자연스럽게 넣는걸 보고 저게 DB에서 어떻게 가능하지? 궁금증이 생겼지만 더 리뷰할 생각 안하고 그러려니 하고 넘겼기 때문에 기본적으로 가지고 있는 지식에 틈이 너무 많았다.

강의를 n회차 듣게 되면서 배웠다. RDBMS에서 컬렉션을 테이블에 저장할 방법은 없다. 가끔 NoSQL 같은곳에서 JSON 데이터를 사용해서 구현하는 방법도 있지만 아직은 RDBMS의 시장이 더 넓기에 컬렉션을 테이블에 저장할 방법을 생각해봐야한다.

현재 관계형 데이터베이스에 기술로 자바에 컬렉션과 가장 유사한 컬렉션 개념은 그냥 새로운 테이블을 만드는것이고 조인 처리 하는거다. 물론 새로 만든 테이블에는 사실상 해당 엔티티에 컬렉션 변수임으로 PK가 엔티티의 PK와 연결이 되어야한다.

정말로 처음 보는 어노테이션이지만 위와 같은 다이어그램을 만들기 위해서는 이런 어노테이션들이 사용될 수 있다.

그러나 저런 어노테이션을 사용하면서 만들게 되면 제약사항이 많다. 그렇기 때문에 다른 솔루션이 필요하다.

객체적으로, 또 테이블 적으로 컬렉션을 구현하기 위해서는 일대다 관계를 만드는게 맞다고 강의에서 설명했다. 마치 매니투매니를 구현하기 위해서 만들었던 다른 객체처럼 추가적인 엔티티를 생성해서 관계를 연결해주는것이 훨씬 더 유리한 전략이라고 볼 수 있다.

profile
성장하는 사람

0개의 댓글