[Springboot] Collection을 값으로 가지는 Column 만들기

김영후·2023년 2월 25일
0

DB를 설계하다보면 굳이 entity를 만들어주어야 하는 것인지 아닌지에 대한 고민이 생길 때가 있다. 내가 이번에 마주한 경우가 바로 그것이다.
이번에 나는 DB를 설계하면서, 객체 하나의 정보를 담고 있는 것들의 집합체라고 볼 수 있는 collection 형태의 필드값을 고안하게 되었다. api를 통해 받고, 반환할 때 따로 변환없이도 원하는 형태로 값을 받고 넘겨주고 싶었기 때문이다. 하지만 이것 때문에 entity하나를 만드는 것에는 많은 생각이 들었다. 하나의 entity를 만들면 코드상 그 entity가 의미를 지닐 수 있을지 의문이 들었기 때문이다.
방법을 여러 번 찾아 본 결과, RDB에서 테이블이 생성되지 않고는 이런 집합체를 저장할 수는 없었다. 하지만 Entity를 생성하지는 않지만 그에 대응되는 테이블을 생성하는 방법이 있었다. 그럼 내가 사용했던 방법에 대해 알아보도록 하자.

Collection 생성

JPA에는 엔티티 타입, 값 타입 이렇게 두 타입이 존재한다. 그 중 오늘 알아볼 것은 값 타입이라고 보면 된다. collection이 값 타입의 한 종류이기 때문이다. 기본값 타입, 임베디드 타입, 값 타입 컬렉션이 있는데 이 중 값 타입 컬렉션이 collection이다.
collection도 두 가지 경우를 생각할 수 있다. 컬렉션을 컬럼으로 나타낼지, 컬렉션을 테이블로 나타내는 것에 대한 경우이다. 나의 경우 컬렉션을 테이블로 나타냈다(다른 경우는 @Embedded에 대해 검색해보길 추천한다.). 이 방법의 첫 번째 스텝이 바로 collection 생성이다. 내가 만든 collection을 예시로 보여주겠다.

@Embeddable annoatation

순수 java class를 생성하듯, 나타내고 싶은 정보에 대한 필드를 정의해준다. 이후 @Embeddable 어노테이션을 사용하여 이 class가 collection으로 사용할 class임을 명시해준다.
이렇게 함으로써 한 entity의 값을 나타내는 collection 테이블을 생성한 것이라고 생각하면 된다.

Entity field 값에 collection table 지정

이제는 아까 정의했던 collection을 entity class에 필드 값으로 지정해주면 된다. 여기서는 @ElementCollection과 @CollectionTable 어노테이션이 세트로 사용되는데, 우선 내가 entity에 정의해준 모습을 보도록 하자.

@ElementCollection

이 어노테이션은 Embeddable 타입의 class를 영속화해주기 위한 어노테이션이다. 프로그램을 내려서 JVM이 죽게 되더라도, 이를 없어지지 않게 하기 위한 것이라고 생각하면 편하다. 자세한 것은 영속화에 대해 검색해보길 추천한다.

@CollectionTable

이 어노테이션을 통해 JPA가 collection table을 생성하는 것이다. 이는 collection으로 하나의 table을 만들어주며, 괄호 안의 옵션을 통해 foreign key를 설정해준다. 옵션을 뜯어보면, (name="생성할 테이블의 이름", joinColumns=@JoinColumn(name="생성할 테이블에서 쓰일 외래키 명", referencedColumnName="이 entity에서 참조할 필드(column) 명"))의 형태이다. 이를 통해 entity를 생성해주지 않고도 컬렉션을 나타내는 하나의 테이블을 만들어줄 수 있다.

DB에서의 table, column


orders(entity)와 order_spesific(collection)의 모습이다. @CollectionTable의 옵션에서 설정해준 orderSpesific이 JPA를 통해 테이블에 매핑될 때 camel case에서 snake case로 매핑된 채로 이름이 설정된다. 여기서 order_spesific의 컬럼을 살펴보면

위의 @Embedabble class에 정의해준 필드들, @CollectionTable의 옵션에서 설정해준 foreign key를 column으로 가지는 테이블이 생성돼있음을 확인할 수 있다.

마무리

나의 경우 코드 상 entity를 하나 생성하는 것이 어색하여 collection table을 이용한 테이블을 생성했지만, 분명 이런 기능이 만들어진 것에는 다른 이유가 있을 것이다. 이에 대해 차차 개발을 해가며 알아 볼 예정이며 올바른 쓰임새를 찾아볼 것이다. 공부 후 여력이 된다면 해당 내용에 대해서도 글을 정리해보도록 하자.

출처
https://developer-hm.tistory.com/48 - collection 관련
https://uchupura.tistory.com/115 - element collection 관련

profile
PNU CSE 16th / Busan, South Korea

0개의 댓글