Spring Boot Entity에서 Enum 사용하기
Spring boot 프로젝트에서 사용하고 있는 Enum 핸들링 방법입니다. 만들게 많아 보이지만 새로운 Enum이 추가될 때 공통을 제외하고 Enum과 컨버터 클래스만 만들어주면 됩니다.
Enum 인터페이스
public interface ConverterEnum {
/**
* 코드
*/
String getCode();
/**
* 코드명
*/
String getCodeName();
}
Enum
@Getter
@RequiredArgsConstructor
public enum CompanyStatusType implements ConverterEnum {
READY("N", "접수"),
APPROVE("Y", "승인"),
DENY("D", "반려"),
TERMINATE("R", "해지"),
NONE(null, "");
private final String code;
private final String codeName;
}
공통 컨버터
import javax.persistence.AttributeConverter;
import java.util.EnumSet;
import java.util.Optional;
@RequiredArgsConstructor
public abstract class AbstractTypeConverter<E extends Enum<E> & ConverterEnum> implements AttributeConverter<E, String> {
private final Class<E> targetEnumClass;
private final boolean nullable;
/**
* Entity의 Enum이 DB로 저장될때 호출되는 메서드
*/
@Override
public String convertToDatabaseColumn(E attribute) {
if(nullable && attribute == null) {
attribute = EnumSet.allOf(targetEnumClass).stream()
.filter(e -> e.getCode() == null)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
String.format("null 값 코드가 %s enum에 존재하지 않습니다.",
targetEnumClass.getName())));
}else if(!nullable && (attribute == null || attribute.getCode() == null)) {
throw new IllegalArgumentException(
String.format("%s enum converter의 nullable이 false이기 때문에 null 값으로 DB에 저장할 수 없습니다.",
targetEnumClass.getName()));
}
return attribute.getCode();
}
/**
* DB에서 읽은 값을 Entity의 Enum으로 컨버트될 때 호출되는 메서드
*/
@Override
public E convertToEntityAttribute(String dbData) {
if(!nullable && !StringUtils.hasText(dbData)) {
throw new IllegalArgumentException(
String.format("%s enum converter의 nullable이 false이기 때문에 null 또는 empty 값을 Enum으로 변환할 수 없습니다.",
targetEnumClass.getName()));
}
return EnumSet.allOf(targetEnumClass).stream()
.filter(e -> CommonUtil.nvl(e.getCode()).equals(CommonUtil.nvl(dbData)))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
String.format("DB에서 읽은 %s 코드값이 %s enum에 존재하지 않습니다.",
dbData, targetEnumClass.getName())));
}
}
컨버터
import javax.persistence.Converter;
@Converter
public class CompanyStatusTypeConverter extends AbstractTypeConverter<CompanyStatusType> {
public CompanyStatusTypeConverter() {
super(CompanyStatusType.class, true); // true: nullable, false: not null
}
}
Entity
@Entity
public class CompanyEntity extends BaseEntity implements Serializable {
...
@Convert(converter = CompanyStatusTypeConverter.class)
private CompanyStatusType CompanyStatusType;
...
}
댓글남기기