CodeLap 프로젝트

CodeLap - enum 클래스를 @ElementCollection으로 매핑하기.

시무룩한개구리 2023. 3. 31. 12:00

@ElementCollection은 엔티티에 컬렉션을 저장하기 위해 사용하는 어노테이션이다.

 

RDB에서는 테이블에 컬렉션을 저장할 수 있는 기능을 지원하지 않기때문에, ORM에서는 객체에 컬렉션을 저장할 수 있는것 처럼 보이지만, 실제로는 스키마에 테이블을 하나 더 만들어서 관리한다.

 

JPA에서는 @ElementCollection을 통해 해당 엔티티에서 컬렉션을 관리한다고 알려줄 수 있다.

 

@ElementCollection
@Enumerated(STRING)
private List<TechStack> techStackList;

 

create table study_tech_stack_list
(
    study_id        bigint not null,
    tech_stack_list varchar(255)
);

alter table study_tech_stack_list
    add constraint FK9f7m49a8kckvtr1s1xxk79ldp foreign key (study_id) references study (id);

해당 프로젝트에서는 플라이웨이로 DB 버전관리를 하는데, techStackList가 따로 테이블로 생성되고, 스터디라는 부모 엔티티에 의해 관리되는 걸 알 수 있다.

 

cascade 옵션이 default 이기 때문에, 부모 데이터가 삭제될 시 해당 테이블의 데이터도 함께 삭제된다.

 

@Embeddable
public enum TechStack {
    JavaScript,
    TypeScript,
    React,
    Vue,
    Svelte,
    Nextjs,
    Nodejs,
    Java,
    Spring,
    Go,
    Nestjs,
    Kotlin,
    Express,
    MySQL,
    MongoDB,
    Python,
    Django,
    php,
    GraphQL,
    Firebase,
    Flutter,
    Swift,
    ReactNative,
    Unity,
    AWS,
    Kubernetes,
    Docker,
    Git,
    Figma,
    Zeplin,
    Jest
}

Enum 클래스에서 Embeddable로 TechStack의 수많은 컬럼들을 하나의 객체로 관리하려고 했었는데, 

 

예외가 발생했다. com.codelap.common.study.domain.Study.techStackList 라는 컬렉션에 대한 persister implementor를 인스턴스화 할 수 없다는 오류메세지였다. 

 

오류가 발생한 원인은 아마 내가 매핑한 컬렉션에 문제가 생긴게 자명했다.

 

결론부터 말하자면, 오류는 @Embeddable 어노테이션 때문에 발생한 것이었다. 이늄 클래스가 아닌 일반 클래스에서는 ElementCollection을 Embeddable 어노테이션과 함께 사용해 하나의 객체로 관리할 수 있는데, 이늄 클래스에서는 안되는 것이었다.

 

내가 enum 클래스에 대한 이해도가 조금 부족했던 것 같다.

 

@Embeddable은 엔티티의 속성을 클래스로 분리할 때 사용된다. 따라서 @Embeddable은 일반적으로 객체 컴포지션을 위해 사용된다.

 

반면에, Enum 클래스는 상수 집합으로 사용되므로 객체 컴포지션과 관련이 없다. 따라서 @Embeddable을 사용할 수가 없다.

 

 

프로젝트를 통해 배우는것이 참 많은 것 같다.