JPA 04 - Enum mapping


Enum

JPA를 사용하여 엔티티를 설계할 때, 특정 필드는 미리 정의된 값들만 가질 수 있도록 Enum을 활용하는 것이 일반적이다. Enum(열거형)은 특정 값들의 집합을 표현하는 데 사용되며, Java에서는 enum 키워드를 사용하여 선언한다.

java enum을 사용하여 JPA에서 DB와 매핑하는 방법은 @Enumerated를 변수에 선언하면 된다. 그리고 선언 옵션은 두가지가 있다.

@Enumerated(EnumType.ORDINAL)

Enum의 순서(ordinal) 값을 DB에 저장하는 방식이다. @Enumerated설정시 기본값으로 설정이 되어 있다. 아래의 예시 코드처럼 사용할 수 있다

@Entity
public class Order {
    @Id @GeneratedValue
    private Long id;
    
    @Enumerated(EnumType.ORDINAL)  // 기본값 (생략 가능)
    private OrderStatus status;
}

public enum OrderStatus {
    PENDING, // 0
    SHIPPED, // 1
    DELIVERED // 2
}

저장되는 값이 정수형으로 저장되는 지라 공간을 절약하고 빠르게 조회가 가능하지만, Enum이 추가되거나 순서가 변경이 되는 경우 데이터가 꼬이는 위험과 직관적으로 값을 해석하기 어려움이 있다.
=> 간단해도 사용하는 건 비추

@Enumerated(EnumType.STRING)

Enum의 String값을 저장하는 형태이다. 아래 예시처럼 사용할 수 있다

@Entity
public class Order {
    @Id @GeneratedValue
    private Long id;
    
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
}

public enum OrderStatus {
    PENDING,
    SHIPPED,
    DELIVERED
}

ORDINAL과 달리 enum 문자열을 그대로 저장할 수 있다. enum 순서가 바꿔도 상관 없고, DB에서 쉽게 파악하기도 편하다.
= 고로 대부분 이 방식을 많이 사용한다.

@JdbcTypeCode(SqlTypes.NAMED_ENUM)

보통 DB의 경우 위의 경우로 해결이 된다지만, 이젠 DB에서 Enumb형식으로 관리를 하는 경우 제대로 값이 저장이 안되는 오류가 생길 것이다. DB에 정의된 enum으로된 형식으로 저장해야 하는데 string또는 varchar로 들어가져서 오류가 날 것이다.

이에 대책인 방법은 @JdbcTypeCode(SqlTypes.NAMED_ENUM)를 사용하는 것이다. 사용 예시는 다음과 같다.

@Entity
public class User {
    @Id @GeneratedValue
    private Long id;
    
    @JdbcTypeCode(SqlTypes.NAMED_ENUM)
    @Column(columnDefinition = "p_user_role_enum")
    private UserRole role;
}

@JdbcTypeCode(SqlTypes.NAMED_ENUM)을 선언한 다음 @Column의 columnDefinition의 값으로 DB의 Enum형태 이름을 지정해주면 된다.

이러면 enum으로 전달할 때 바로 DB Enum형태로 저장을 할 수 있게 된다.