반응형

 

 

@ElementCollection


 

Jpa 에서 엔티티가 아닌 값 타입 컬렉션을 저장하기 위한 어노테이션이다. 

 

 

개념


 

JPA에서 @Entity는 식별자(@Id)를 갖는 객체를 의미하지만, 

@ElementCollection은 식별자 없는 단순 값(String, int, Enum)등 의 모음을 다룰 때 사용합니다. 

 

예를 들어 User 엔티티에 여러 개의 권한 문자열(role)을 저장하고 싶을 때, 

@Entity를 새로 만들 필요 없이 List<String>으로 바로 저장 가능하게 해줍니다.

 

 

코드


 

@Entity
public class User {

    @Id @GeneratedValue
    private Long id;

    private String username;

    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(
        name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id")
    )
    private List<String> roles = new ArrayList<>();
}

 

 

동작 방식


 

위 코드가 실행되면 두 개의 테이블이 자동으로 생성됩니다. 

명시적으로 지정하지 않으면 이름은 엔티티명_필드명 형태로 생성됩니다. 

 

 

주의사항


 

@ElementCollection 은 단순해 보이지만, 언제 써야 하고 언제 피해야 하는지 구분이 매우 중요합니다. 

 

장점과 단점을 먼저 확인을 해보자면 

장점 단점
DB에 자동으로 보조 테이블 생성 @Id 없음, 개별 조회/수정 불가
권한 목록, 태그, 키워드처럼 단순한 값 집합 관리에 적합 @Query 등으로 복잡한 검색 불가능 
별도 @Entity 필요 없으니 코드 가볍고 직관적 대규모 데이터나 자주 변경되는 컬렉션엔 비적합

 

즉 읽기 중심의 간단한 값 집합에 적합합니다. 

따라서 유저 권한 같은 값또한 ElementCollection을 사용하면 안됩니다. 

관리자가 유저의 권한을 변경할 수 있어야 하고, 누가 언제 권한을 바꿨는지 기록도 남겨야 하기 때문입니다. 

 

 

변경이 자주 일어나는 데이터에는 부적합


 

1. 전체 삭제 후 재삽입 구조입니다. 

 

JPA는 값 컬렉션이 변경될 때 변경된 부분만 UPDATE 하지 못하고 기존 row 전부 DELETE 후 새로 INSERT 합니다.

즉 관리자가 권한을 하나만 바꿔도 전부 지우고 다시 저장해버립니다. 비효율 적이고 트랜잭션 리스크가 생깁니다. 

 

2. 엔티티 아님

 

@ElementCollection으로 저장된 값은 독립적인 엔티티가 아니라서 @Id, createAt, updateAt, 변경자등 관리가 불가능합니다.

누가 언제 권한을 바꿨는지 기록도 못남깁니다. 

 

3. 조회 제약

 

특정 권한을 가진 유저 검색 같은 쿼리시 조인이나 서브쿼리가 필요하고, 

역할 엔티티가 없기 때문에 효율적인 인덱스 관리도 어렵습니다. 

 

 

정리


 

별도 엔티티로 관리하거나, enum클래스로 관리하는 것이 제일 좋습니다. 

728x90
반응형