我会回答我自己的问题。正如评论中提到的,解决方案是使用Converter
.
这是我打算用我的类模型实现的示例:
A Contact
可以是Person
or an Organisation
.
如果您使用的是 spring-data-mongodbMongo存储库 https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/repository/MongoRepository.html根据实体模型将数据写入数据库,_class
字段将被添加到文档根和复杂属性类型(请参阅本节 https://docs.spring.io/spring-data/data-mongodb/docs/current/reference/html/#mongo-template.type-mapping)。该字段存储 Java 类的完全限定名称,并且在从 MongoDb 文档映射到 Spring 数据模型时可以消除歧义。
如果您的应用程序只是从数据库中读取文档(没有_class
fields),你需要告诉 Spring data 在映射时要实例化哪个类Contact
。 Spring-data 允许您使用自定义默认类型映射行为Converter
。使用显式Converter
覆盖类的默认映射 https://docs.spring.io/spring-data/mongodb/docs/2.1.2.RELEASE/reference/html/#mapping-explicit-converters。你需要明确地映射你的整个类。这是我的一个例子联系阅读转换器:
@ReadingConverter
public class ContactReadConverter implements Converter<Document, Contact> {
@Override
public Contact convert(Document source) {
if (source.get("firstName") == null) {
Organisation organisation = new Organisation();
I18n name = new I18n();
name.setEn(source.get("name", Document.class).get("en", String.class));
name.setFr(source.get("name", Document.class).get("fr", String.class));
organisation.setName(name);
organisation.setAcronym(source.get("acronym", String.class));
organisation.setRole(source.get("role", String.class));
return organisation;
}
Person person = new Person();
person.setFirstName(source.get("firstName", String.class));
person.setLastName(source.get("lastName", String.class));
person.setRole(source.get("role", String.class));
person.setEmail(source.get("email", String.class));
person.setOrcId(source.get("orcId", String.class));
if (source.get("organisation") != null) {
Document sourceOrg = source.get("organisation", Document.class);
Organisation organisation = new Organisation();
organisation.setAcronym(sourceOrg.get("acronym", String.class));
organisation.setRole(sourceOrg.get("role", String.class));
if (sourceOrg.get("name") != null) {
I18n name = new I18n();
name.setFr(sourceOrg.get("name", Document.class).get("fr", String.class));
name.setEn(sourceOrg.get("name", Document.class).get("en", String.class));
organisation.setName(name);
}
person.setOrganisation(organisation);
}
return person;
}
}
然后,需要注册新定义的转换器:
@Configuration
public class DataportalApplicationConfig extends AbstractMongoConfiguration {
@Value("${spring.data.mongodb.uri}")
private String uri;
@Value("${spring.data.mongodb.database}")
private String database;
@Override
public MongoClient mongoClient() {
return new MongoClient(new MongoClientURI(uri));
}
@Override
protected String getDatabaseName() {
return database;
}
@Bean
@Override
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converterList = new ArrayList<>();
converterList.add(new ContactReadConverter());
return new MongoCustomConversions(converterList);
}
}
希望能帮助到你。