Backend/spring boot

spring boot JPA : 컬렉션 형태의 데이터를 저장하기(@ElementCollection)

attlet 2023. 6. 17. 02:11

데이터베이스에 단일값이 아닌 컬렉션 형태(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를 하는 방식을 사용한다. 

 

 

 

여기서 마지막 부분을 알고 가자면, 값 타입은 엔티티와 달리 식별자를 갖지 않는다. 이는 엔티티의 속성으로 사용되어 식별자를 둬서 구분할 필요가 없기 때문이다.

 

 

 

문제는 이것이 컬렉션으로 모여 있는 상황에서 수정할 부분을 찾을 때 식별자가 따로 없어 찾을 수 없기에, 모두 삭제한 후 새로 작성해서 넣는 방식을 사용한다.