도찐개찐

[SpringBoot] MongoDB에 _class 필드를 빼는 방법 본문

JAVA/SpringBoot

[SpringBoot] MongoDB에 _class 필드를 빼는 방법

도개진 2023. 7. 21. 10:57

https://dev-truly.tistory.com/entry/SpringBoot-MongoDB-%EC%84%A4%EC%B9%98-%EB%B0%8F-MongoTemplate-vs-MongoRepository-%EB%B9%88%EB%93%B1%EB%A1%9D-%EA%B4%80%EB%A6%AC

 

[SpringBoot] MongoDB 설치 및 MongoTemplate vs MongoRepository 빈등록 관리

[MongoDB] 사용자 계정 생성 및 권한 관리 일반적으로 DB 서버에서 사용하는 계정의 종류는 크게 두 가지로 나눌 수 있습니다. DB 관리자가 사용하는 어드민용 계정과 실제 애플리케이션 서버에서 DB

blog.dev-truly.dev

_class 필드는 무슨 필드지?

스프링 부트(Spring Boot)에서 spring-data-mongodb를 사용하여 MongoDB와 연동할 때, 데이터를 저장하려고 하면 _class라는 필드가 자동으로 삽입된다. 별다른 설정을 하지 않았다면 아래와 같이 객체를 저장할 때 자동으로 클래스의 패키지 정보가 함께 저장되는 것을 볼 수 있습니다.

 

use montest;
db.user.find();

_class 필드의 용도 : Spring Data MongoDB가 객체를 DB에 저장하고 다시 객체로 읽어오는 과정에서 클래스 정보를 유지하기 위해서입니다. _class 필드에는 해당 객체의 Java 클래스 이름이 저장됩니다.

_class 필드를 빼고 저장 하려면?

MongoDB를 리액티브(reactive)로 사용하는 spring-boot-starter-data-mongodb-reactive 의존성을 기반으로 아래와 같이 설정하면 된다. 다른 부분은 각자 프로젝트에 맞게 설정하면 되지만, 핵심은 DefaultMongoTypeMapper를 설정하는 부분이다. 이 설정을 변경하면 _class 필드를 저장하지 않도록 설정할 수 있습니다.

@Configuration
@EnableReactiveMongoRepositories(basePackages = "com.madplay.taengtest",
        reactiveMongoTemplateRef = "simpleReactiveMongoTemplate")
public class MongoConfiguration {

    private final MongoMappingContext mongoMappingContext;

    public MongoConfiguration(MongoMappingContext mongoMappingContext) {
        this.mongoMappingContext = mongoMappingContext;
    }

    @Bean
    public ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoClient mongoClient) {
        return new SimpleReactiveMongoDatabaseFactory(mongoClient, "taeng");
    }

    @Bean
    public MappingMongoConverter reactiveMappingMongoConverter() {
        MappingMongoConverter converter = new MappingMongoConverter(ReactiveMongoTemplate.NO_OP_REF_RESOLVER,
                mongoMappingContext);

        // '_class' 필드를 제거하는 설정
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return converter;
    }

    @Bean
    public ReactiveMongoTemplate simpleReactiveMongoTemplate(ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory,
                                                             MappingMongoConverter reactiveMappingMongoConverter) {
        return new ReactiveMongoTemplate(reactiveMongoDatabaseFactory, reactiveMappingMongoConverter);
    }
}
주의 사항 : 
_class 필드는 Spring Data MongoDB가 해당 도큐먼트의 원본 클래스를 추적하도록 돕는 역할을 합니다. 도큐먼트가 저장될 때, 이 필드에는 해당 객체의 완전한 클래스 이름이 저장됩니다. 도큐먼트가 다시 읽혀질 때, 이 필드를 통해 원본 객체의 클래스를 확인하고, 해당 클래스의 인스턴스를 생성하여 도큐먼트의 데이터를 복원합니다.

즉, _class 필드가 없으면 도큐먼트를 읽을 때 원본 클래스를 알 수 없으므로, 원본 객체의 정확한 타입을 복원하는 것이 어렵습니다. 물론, 동일한 컬렉션에 한 종류의 클래스만 저장하는 경우에는 문제가 되지 않습니다. 그러나 동일한 컬렉션에 여러 종류의 클래스를 저장하는 경우, _class 필드 없이는 각 도큐먼트의 원본 클래스를 정확히 알 수 없습니다.

위 방법을 사용하는 경우 MongoDB에 저장된 데이터를 Java 객체로 변환할 때 기본 클래스를 사용하거나, 클래스 정보를 추정하는 방법을 사용해야 합니다. 예를 들어, 특정 필드의 존재 여부를 기반으로 클래스를 결정하는 등의 방법이 있습니다.
하지만 이런 방법들은 _class 필드를 사용하는 것보다 복잡하고, 제한적일 수 있습니다.
_class 필드의 값을 클래스명이 아닌 다른 값으로 Alias 하는 방법

document 객체에 

@TypeAlias 어노테이션을 써 간단하게 수정이 가능 합니다.

package com.example.mongotest.documents;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@Document(collection = "user")
// _class 필드에 `dev-truly` 로 저장
@TypeAlias("dev-truly")
public class MongoUser {
    @Id
    private String _id;
    private String userId;
    private String userName;
    private String userPwd;
    private String userMobile;
}

 

 

 

 

728x90
Comments