데이터베이스에 단일값이 아닌 컬렉션 형태(list 같은) 값을 넣는 것은 RDB에서 허용되지 않는다. 이 때문에 컬렉션 형태의 값이 필요하다면, 추가적인 테이블을 만든 뒤 그 테이블과 연관관계를 형성하는 방법을 사용해야 한다.
이 때 사용되는 방법이 @ElementCollection을 사용하는 것이다.
@ElementCollection
public class Post extends BaseEntity {
@Column(nullable = false)
private String type;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String text;
@Column
private String proceed_method; //진행 방식
@Column
private int comment_cnt;
@Column
private LocalDateTime period; //예상 기간
@ElementCollection
private List<String> rolesNeeded; // 작성자가 구하고자 하는 역할군들
}
이렇게 값 타입 컬렉션을 @ElementCollection을 이용해 DB에 저장하는 것이다.
글 작성자는 구인 게시글을 작성하는 것이고, 글에는 구하고자 하는 역할군들이 보여진다.
여기서 작성자 입장에서는 웹 개발자들뿐 아니라 게임 개발자를 구할 수도 있다. 이것으로 볼 때, 역할군은 값 타입 컬렉션으로 저장해야 하며, 개념적으로 보면 post와 roleNeeded는 1 : N 관계를 갖는다고도 볼 수 있다.
ElementCollection은 별도로 매핑하는 테이블을 생성하며, 이곳에 컬렉션을 관리하게 된다.
@CollectionTable
@ElementCollection을 사용할 때, 같이 사용할 수 있는 어노테이션이 CollectionTable이다. ElementCollection으로 인해 자동으로 생성되는 테이블에 대한 정보를 지정하는 데 사용한다. 물론 생략도 가능하다.
생략하면 생성하는 테이블 이름은 {엔티티 이름}_{컬렉션 지정한 필드 이름} 이 된다.
@ElementCollection
@CollectionTable(name = "role_need_table" )
private List<String> roleNeeded = new Array<>();
추가로 생성되는 테이블과 연결하는 fk도 joinColumns 필드를 통해 지정할 수 있다.
@ElementCollection의 특징
ElementCollection은 다음과 같은 특징을 가진다.
- 만들면 그 엔티티에만 연관된다. 부모 엔티티라 보면 된다. 부모 엔티티를 통해서만 그 값 타입 컬렉션에 접근이 가능하다.
- 지연 로딩(lazy loading)을 지원한다. 즉 실제로 이 컬렉션을 사용할 때에만 접근하도록 하는 것이 가능하다.
- 다양한 컬렉션 형태를 지원한다. List, Hashmap, set등을 사용할 수 있다.
- 부모 엔티티와 생명주기가 같다. 일대다 관계에서 cascade = ALL이 상시로 적용된다고 보면 된다.
- 컬렉션 값을 수정할 때, update쿼리가 아닌 delete로 데이터 삭제 후 insert를 하는 방식을 사용한다.
여기서 마지막 부분을 알고 가자면, 값 타입은 엔티티와 달리 식별자를 갖지 않는다. 이는 엔티티의 속성으로 사용되어 식별자를 둬서 구분할 필요가 없기 때문이다.
문제는 이것이 컬렉션으로 모여 있는 상황에서 수정할 부분을 찾을 때 식별자가 따로 없어 찾을 수 없기에, 모두 삭제한 후 새로 작성해서 넣는 방식을 사용한다.
'Backend > spring boot' 카테고리의 다른 글
spring boot jpa : hibernate delete 쿼리가 실행되지 않는 현상 (0) | 2023.08.31 |
---|---|
spring boot에서 DTO를 엔티티로 변환할 때 연관관계에 있는 엔티티와 연결하기 (0) | 2023.08.15 |
외부에서 spring boot 서버에 접속 해보기(접속 안 될 때 이슈, sk 브로드밴드 포트포워딩) (0) | 2023.08.11 |
spring boot 사이드 프로젝트 : service 테스트 (0) | 2023.07.12 |
spring boot JPA : 페이징(paging) (0) | 2023.05.25 |