Spring
[ Spring ] enum의 원하는 상태 값을 DB에 저장하기
자바니또
2022. 3. 23. 15:45
JPA
를 사용하면서 엔티티의 상태 값 중 enum이 있을 때 enum의 순서(상수 값)나 이름(문자열 값)이 아니라 원하는 데이터를 저장하고 꺼내고 싶을 수 있습니다. JPA 2.1
부터는 AttributeConverter
를 제공하여 이것이 가능하도록 해줍니다.
(JPA 구현체 중 Hibernate 5 기준입니다.)
문제 상황 예시
은행 코드 enum인 BankCode
가 있습니다. DB에 저장할 때 BankCode
의 코드 값이 DB에 저장되고, 엔티티로 직렬화 할 때도 코드 값을 통해 가능하도록 하고 싶습니다.
엔티티는 다음과 같습니다.
@Entity
public class BankTransaction {
@Id
@Column(name = "bank_transaction_id")
private Long id;
@Column(name="bank_code", nullable = false)
private BankCode bankCode;
}
@Getter
@RequiredArgsConstructor
public enum BankCode {
KB("004", "국민은행"),
NH("011", "농협은행");
private final String code;
private final String bankName;
public static BankCode ofCode(String code) { /*변환*/ }
}
@Enumerated(value = EnumType.ORDINAL)
나 @Enumerated(value = EnumType.STRING)
는 원하는 결과를 만들 수 없습니다. 원하는 건 DB에 004
나 011
처럼 코드로 저장 되는 것입니다.
Converter 만들기
javax.persistence.AttributeConverter
를 구현한 컨버터 클래스를 만들고convertToDatabaseColumn
과convertToEntityAttribute
를 오버라이딩 합니다.
@Converter
public class BankCodePersistConverter implements AttributeConverter<BankCode, String> {
@Override
public String convertToDatabaseColumn(BankCode attribute) {
if (attribute == null) {
throw new IllegalArgumentException("BankCode가 null입니다.");
}
return attribute.getCode();
}
@Override
public BankCode convertToEntityAttribute(String dbData) {
if (dbData == null || dbData.isBlank()) {
throw new IllegalArgumentException("dbData가 비어있습니다.");
}
return BankCode.ofCode(dbData);
}
}
두 메서드는 이름에서 알 수 있듯이 DB에 저장할 때와 Entity의 상태 값으로 변환할 때 사용됩니다.
- 엔티티의 enum 상태 값에 @Convert를 사용하여 컨버터를 지정합니다.
@Entity
public class BankTransaction {
@Id
@Column(name = "bank_transaction_id")
private Long id;
@Convert(converter = BankCodePersistConverter.class) // 컨버터 지정
@Column(name="bank_code", nullable = false)
private BankCode bankCode;
}