Spring Boot和MongoDB如何删除“_class”列?

26

在向 MongoDB 插入数据时,Spring Data 会添加一个自定义的 "_class" 列,有没有一种方法可以在使用 Spring Boot & MongoDB 时消除 "class" 列?

还是说我需要创建一个自定义类型映射器?

有任何提示或建议吗?


12个回答

20

戴夫的回答是正确的。然而,我们通常建议不要这样做(这也是为什么默认情况下启用它的原因),因为您有效地放弃了保留类型层次结构甚至是简单属性集合到例如 Object 的机会。假设以下类型:

@Document
class MyDocument {

  private Object object;
}
如果你现在将object设置为一个值,它将被愉快地持久化,但是你无法以原始类型读取该值回来。

如果您现在将object设置为一个值,那么该值将会被愉快地持久化,但是您无法以原始类型读取该值回来。


感谢 @Oliver 提供的额外细节,一开始我认为 _class 是无用的,但是通过 Spring Data 提供的“魔法”,现在它更有意义了。 - Jeach
1
@Oliver:虽然我认为你的观点在一般情况下很重要,但是有一个例外情况,我认为这是主要的用例。如果有一个MongoRepository<T,ID>映射到集合(并且希望该集合不会被映射到其他任何东西),而T不是抽象的,并且没有使用@Entity的继承类,则我肯定应该能够删除_class而不影响该repo正确地填充T的能力。你同意吗,或者我忽略了其他障碍? - Levente Pánczél

18

针对这个问题,有一个更加更新的答案,就是使用嵌入式MongoDB进行测试用例:

Spring Data MongoDB在mongo文档中添加了_class以处理java继承的多态行为。如果您想要删除_class,只需在代码中引入以下配置类。

我从http://mwakram.blogspot.fr/2017/01/remove-class-from-mongo-documents.html引用。
package com.waseem.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

@Configuration
public class MongoConfig {

 @Autowired MongoDbFactory mongoDbFactory;
 @Autowired MongoMappingContext mongoMappingContext;

 @Bean
 public MappingMongoConverter mappingMongoConverter() {

  DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
  MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
  converter.setTypeMapper(new DefaultMongoTypeMapper(null));

  return converter;
 }
}

你好,我遇到了一个问题 - Error creating bean with name 'mongoDBConfig': Unsatisfied dependency expressed through field 'mongoDbFactory' - iamcrypticcoder
mongoDbFactory更改为mongoDatabaseFactory,并更新导入为org.springframework.data.mongodb.MongoDatabaseFactory - rishimaharaj

11
这里有一个稍微简单一些的方法:
@Configuration
public class MongoDBConfig implements InitializingBean {

    @Autowired
    @Lazy
    private MappingMongoConverter mappingMongoConverter;

    @Override
    public void afterPropertiesSet() throws Exception {
        mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
    }
}

8
您可以使用以下代码删除_class。您可以在mongo配置类中使用此代码。
@Bean
    public MongoTemplate mongoTemplate(MongoDatabaseFactory databaseFactory, MappingMongoConverter converter) {
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return new MongoTemplate(databaseFactory, converter);
    }

8

4

类似于RZet,但避免使用继承:

@Configuration
public class MongoConfiguration {

    @Autowired
    private MappingMongoConverter mappingMongoConverter;

    // remove _class
    @PostConstruct
    public void setUpMongoEscapeCharacterConversion() {
        mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
    }

}

1
一个简单的方法(+用于ReactiveMongoTemplate):
  @Configuration
  public class MongoDBConfig {

    @Autowired
    private MongoClient mongoClient;

    @Value("${spring.data.mongodb.database}")
    private String dbName;

    @Bean
    public ReactiveMongoTemplate reactiveMongoTemplate() {
      ReactiveMongoTemplate template = new ReactiveMongoTemplate(mongoClient, dbName);
      MappingMongoConverter converter = (MappingMongoConverter) template.getConverter();
      converter.setTypeMapper(new DefaultMongoTypeMapper(null));
      converter.afterPropertiesSet();
      return template;
    }
  }

0

添加一个转换器以删除类。

MappingMongoConverter converter =
        new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext());
    converter.setTypeMapper(new DefaultMongoTypeMapper(null));

MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);

    return mongoTemplate;

`


0

使用响应式Mongo的Spring Boot 3。

package es.dmunozfer.trading.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
@EnableReactiveMongoRepositories("es.dmunozfer.trading.repository")
public class MongoConfig extends AbstractReactiveMongoConfiguration {

    @Autowired
    private MongoProperties mongoProperties;

    @Override
    protected String getDatabaseName() {
        return mongoProperties.getDatabase();
    }

    @Bean
    @Override
    public MappingMongoConverter mappingMongoConverter(ReactiveMongoDatabaseFactory databaseFactory, MongoCustomConversions customConversions,
            MongoMappingContext mappingContext) {
        MappingMongoConverter converter = super.mappingMongoConverter(databaseFactory, customConversions, mappingContext);
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return converter;
    }
}

0

我把这个答案留在这里,以防有人想从Kotlin中删除_class并更新它,因为之前的答案有几个已弃用的依赖项。

import org.springframework.beans.factory.BeanFactory
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.mongodb.MongoDatabaseFactory
import org.springframework.data.mongodb.core.convert.DbRefResolver
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper
import org.springframework.data.mongodb.core.convert.MappingMongoConverter
import org.springframework.data.mongodb.core.mapping.MongoMappingContext


@Configuration
internal class SpringMongoConfig {

    @Bean
    fun mappingMongoConverter(
        factory: MongoDatabaseFactory, context: MongoMappingContext,
        beanFactory: BeanFactory
    ): MappingMongoConverter {
        val dbRefResolver: DbRefResolver = DefaultDbRefResolver(factory)
        val mappingConverter = MappingMongoConverter(dbRefResolver, context)
        mappingConverter.setTypeMapper(DefaultMongoTypeMapper(null))
        return mappingConverter
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接