在向 MongoDB 插入数据时,Spring Data 会添加一个自定义的 "_class" 列,有没有一种方法可以在使用 Spring Boot & MongoDB 时消除 "class" 列?
还是说我需要创建一个自定义类型映射器?
有任何提示或建议吗?
在向 MongoDB 插入数据时,Spring Data 会添加一个自定义的 "_class" 列,有没有一种方法可以在使用 Spring Boot & MongoDB 时消除 "class" 列?
还是说我需要创建一个自定义类型映射器?
有任何提示或建议吗?
戴夫的回答是正确的。然而,我们通常建议不要这样做(这也是为什么默认情况下启用它的原因),因为您有效地放弃了保留类型层次结构甚至是简单属性集合到例如 Object
的机会。假设以下类型:
@Document
class MyDocument {
private Object object;
}
如果你现在将object
设置为一个值,它将被愉快地持久化,但是你无法以原始类型读取该值回来。
如果您现在将object
设置为一个值,那么该值将会被愉快地持久化,但是您无法以原始类型读取该值回来。
@Entity
的继承类,则我肯定应该能够删除_class而不影响该repo正确地填充T的能力。你同意吗,或者我忽略了其他障碍? - Levente Pánczél针对这个问题,有一个更加更新的答案,就是使用嵌入式MongoDB进行测试用例:
我从http://mwakram.blogspot.fr/2017/01/remove-class-from-mongo-documents.html引用。Spring Data MongoDB在mongo文档中添加了_class以处理java继承的多态行为。如果您想要删除_class,只需在代码中引入以下配置类。
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'
。 - iamcrypticcodermongoDbFactory
更改为mongoDatabaseFactory
,并更新导入为org.springframework.data.mongodb.MongoDatabaseFactory
。 - rishimaharaj@Configuration
public class MongoDBConfig implements InitializingBean {
@Autowired
@Lazy
private MappingMongoConverter mappingMongoConverter;
@Override
public void afterPropertiesSet() throws Exception {
mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
}
}
@Bean
public MongoTemplate mongoTemplate(MongoDatabaseFactory databaseFactory, MappingMongoConverter converter) {
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
return new MongoTemplate(databaseFactory, converter);
}
我认为你需要创建一个类型为MongoTemplate
的@Bean
,并明确设置类型转换器。详见(不涉及Boot,仅提取模板配置):http://www.mkyong.com/mongodb/spring-data-mongodb-remove-_class-column/
类似于RZet,但避免使用继承:
@Configuration
public class MongoConfiguration {
@Autowired
private MappingMongoConverter mappingMongoConverter;
// remove _class
@PostConstruct
public void setUpMongoEscapeCharacterConversion() {
mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
}
}
@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;
}
}
添加一个转换器以删除类。
MappingMongoConverter converter =
new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
return mongoTemplate;
`
使用响应式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;
}
}
我把这个答案留在这里,以防有人想从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
}
}