MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Spring Data Mongo - Comment mapper les entités POJO héritées ?

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.