[트러블슈팅] 몽고DB Field값을 Enum으로 역직렬화하기 (2)

wannabeing·2025년 8월 29일
0

알쓸코잡

목록 보기
22/22
post-thumbnail

문제가 생겼다..

문제개요

1. Enum.value()는 소문자 값이다.

현재 Enum 클래스는 아래와 같이 소문자를 value 필드로 저장하고 있다.

@Getter
@RequiredArgsConstructor
public enum AlbumType {
	ALL("all"),
	MAIN("main"),
	INFANTS("infants")

    private final String value;
    
    public static AlbumType deserialize(String type){
		for(AlbumType albumType : AlbumType.values()){
			if(albumType.getValue().equalsIgnoreCase(type.trim())){
				return albumType;
			}
		}
		throw new AlbumException(AlbumExceptionCode.ILLEGAL_ALBUM_TYPE);
	}
    ...

2. MongoDB에는 소문자로 저장되어 있다.

아래 사진과 같이 type필드에 소문자(value)로 저장되어 있다.

3. Mongo Converter를 통해 DB String(소문자) → Enum 클래스로 역직렬화를 성공했다.

@Configuration
public class MongoConverterConfig {
	@Bean
	public MongoCustomConversions mongoCustomConversions() {
		return new MongoCustomConversions(List.of(
			// DB -> Enum
			new Converter<String, AlbumType>() {
				@Override
				public AlbumType convert(String albumType) {
					return AlbumType.deserialize(albumType);
				}
			},
            ....
  • MongoDB에서 데이터를 조회할 때(역직렬화), Converter를 사용해서
    DB에 저장된 String(소문자)을 Enum의 value(소문자) 필드와 비교하여 역직렬화를 성공했었다.

원인분석 및 해결책

4. (문제발생) 모든 String을 역직렬화하려고 한다 ㅠ

public class RequestDto {
	...
    private String 다른필드1;
    private String 다른필드2;
	private String type;
    ...
  • 해당 요청DTO의 type값만 Enum 역직렬화 할 때,
    모든 String을 Enum(AlbumType) 클래스로 변환하려고 하였다.
  • type 필드만 Enum 클래스로 매핑해야되는데, 다른필드1, 다른필드2
    Enum 클래스로 역직렬화를 시도했다.

5. 몽고DB 전용컨버터로 변경하자!

  • 읽기 변환(ReadingConverter): DB에서 조회할 때 사용하는 컨버터
    (String(소문자) → AlbumType)
  • 쓰기 변환(WritingConverter): MongoDB에 저장할 때 사용하는 컨버터
    (AlbumType → String(소문자))

내가 원하는 정확한 기능이였다.
이름으로도 쉽게 구분할 수 있었다!

[생성시]
요청 폼(String 소문자) → Enum 클래스 매핑(deseriaize 함수 사용)하여 엔티티 생성
→ DB에 소문자(Enum.value())로 저장 (이 때, 컨버터 사용됨)

[조회시]
DB(String 소문자) → Enum 클래스 매핑(컨버터 사용)하여 엔티티 생성
→ 응답에 소문자(Enum.getValue())
@Configuration
public class MongoConverterConfig {
	@ReadingConverter
	public static class stringToAlbumTypeConverter implements Converter<String, AlbumType> {
		@Override
		public AlbumType convert(String albumType){
			return AlbumType.deserialize(albumType);
		}
	}
	@WritingConverter
	public static class albumTypeToStringConverter implements Converter<AlbumType, String> {
		@Override
		public String convert(AlbumType albumType) {
			return albumType.getValue(); // enum 내부 커스텀 값
		}
	}

	/**
	 * 커스컴 컨버터 Bean
	 */
	@Bean
	public MongoCustomConversions mongoCustomConversions() {
		return new MongoCustomConversions(List.of(
			new stringToAlbumTypeConverter(),
			new albumTypeToStringConverter()
		));
	}
    ....
  • stringToAlbumTypeConverter
    소문자 String을 AlbumType으로 매핑해주는 컨버터
  • albumTypeToStringConverter
    AlbumType을 소문자 String으로 매핑해주는 컨버터
  • mongoCustomConversions
    두 컨버터를 몽고DB 관련 매핑할 때, 사용한다고 선언

해결!


profile
wannabe---ing

0개의 댓글