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

wannabeing·2025년 8월 27일
0

알쓸코잡

목록 보기
20/22
post-thumbnail

문제개요 및 오류코드

No enum constant org.example.luvbackend.entity.AlbumType.main

몽고DB의 Collection Field값을 Enum으로 역직렬화중에 뜨는 에러이다.

몽고DB Document 값과 Enum 코드를 살펴보자.

public enum AlbumType {
	ALL("all"),
	GEN_3040("3040"),
    ...
  • 이미 데이터가 존재하는 DB 컬렉션이라 type을 모두 GEN_3040 등으로 바꾸기보다
    Enum의 필드값으로 직렬화/역직렬화가 하고 싶었다.
  • 소문자로 저장되어있기 때문에 소문자로 변환하고 싶다.

원인분석 및 해결책

1. 스프링과 MongoDB 사이에는 Spring Data MongoDB가 있다.

Spring Data MongoDB는 JPA(Object-Relational Mapper)와 비슷한
MongoDB의 Document ↔ Java 객체(Object) 매핑을 담당하는
ODM(Object-Document Mapper)이다.

여기서 Document는 실제 데이터 객체 1개이다.
RDB에서는 테이블의 하나의 열과 같은 뜻이다.

2. Spring Data MongoDB는 Enum으로 매핑할 때, Enum.name()이 기본전략이다.

이건 JPA도 그런거 같기도..? 쨋든 기본전략이기 때문에 Enum.필드값()으로 바꾸지 못하는 듯하다 ㅠ

3. Spring Data MongoDB는 자바 객체로 바꿀 때, Converter를 사용한다.

내부적으로 MappingMongoConverter가 BSON ↔ Entity 매핑한다.

  • MongoDB는 JSON와 비슷한 BSON(Binary JSON)을 사용한다.

4. Jackson(JSON 변환 라이브러리)를 쓰면 되지 않을까?

안된다..

  • BSON
    • Jackson 라이브러리는 기본적으로 BSON을 지원하지 않는다.
      bson4jackson 플러그인을 따로 추가하면 지원된다고 한다.
  • HTTP 요청/응답
    • 애초에 Jackson 라이브러리는 HTTP 요청/응답 계층에서 사용된다.
    • 클라이언트에서 HTTP 요청에 담겨진 JSON을 변환할 때,
    • 서버에서 HTTP 응답으로 JSON을 변환할 때에 사용된다.

✅ 따라서 커스텀 Converter를 추가하자.

MongoCustomConversions(Bean)에 커스텀 Converter 등록

  • Converter<String, AlbumType> (DB String → Enum.value() 매핑)
  • Converter<AlbumType, String> (Enum → DB 저장 시 value 사용)
  • Hibernate의 AttributeConverter 같은 역할을 Mongo에서도 구현하는 것이다.
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;

@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);
				}
			},
			// Enum -> DB
			new Converter<AlbumType, String>() {
				@Override
				public String convert(AlbumType albumType) {
					return albumType.getValue();
				}
			}
		));
	}
}

커스텀 컨버터가 많아질 수도 있는 데이터 구조일 경우, 다른 방법(DB 데이터 변경 등)을 고려해보는 것도 좋다고 생각한다.

나의 경우 커스텀 컨버터가 추후에도 추가된다 할지라도 몇개 추가 안될꺼라 생각해서 적용하였다!


출처

MongoDB Collection~
Jackson 라이브러리
@JsonCreator로 Enum 역직렬화하기
Spring boot with MongoDB - Spring Data MongoDB

profile
wannabe---ing

0개의 댓글