Je vais répondre à ma propre question. Comme mentionné dans les commentaires, la solution consiste à utiliser Converter
.
Voici un exemple de ce que j'avais l'intention de réaliser avec mon modèle de classe :
Un Contact
peut être soit une Person
ou une Organisation
.
Si vous utilisez spring-data-mongodb MongoRepository
pour écrire des données dans votre base de données selon votre modèle d'entité, un _class
le champ sera ajouté aux racines du document et aux types de propriétés complexes (voir cette section
). Ces champs stockent le nom complet de la classe Java et permettent la désambiguïsation lors du mappage du document MongoDb au modèle de données Spring.
Si votre application vient de lire le document de la base de données (pas de _class
champs), vous devez indiquer à Spring data quelle classe instancier lors du mappage d'un Contact
. Spring-data vous permet de personnaliser le comportement de mappage de type par défaut à l'aide de Converter
. Utiliser un Converter
explicite remplacer la valeur par défaut mappage pour la classe
. vous devez mapper explicitement toute votre classe. Voici un exemple de mon ContactReadConverter :
@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;
}
}
Ensuite, les convertisseurs nouvellement définis doivent être enregistrés :
@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);
}
}
J'espère que ça aide.