Spring Data Mongo - Как отобразить унаследованные объекты POJO? - PullRequest
0 голосов
/ 07 ноября 2018

Я довольно новичок в Spring, но я хочу попробовать его в этом проекте. У меня есть база данных MongoDB, заполненная довольно сложными документами. Я хочу использовать Spring data Mongo для запроса (без других операций CRUD) к базе данных.

Я уже описал свою сущность документа, используя POJO, но некоторые из них являются абстрактными (см. GeometryGeoJSON используется для принятия всех типов геометрии GeoJson, или Contact, который может быть Person или Organisation. ссылка на репозиторий GitHub приведена ниже).

Имея тест с этим определением сущности, выдается java.lang.InstantiationError, что справедливо, поскольку в этих абстрактных классах не задан Contructor.

Вот GitHub репозиторий на случай, если вам нужно посмотреть.

Я чувствую себя немного растерянным со всем этим, но я буду более внимательно смотреть на документацию.

Как бы вы столкнулись с этой проблемой?

1 Ответ

0 голосов
/ 09 ноября 2018

Я отвечу на свой вопрос. Как уже упоминалось в комментариях, решение заключается в использовании Converter.

Вот пример того, чего я намеревался достичь с помощью модели моего класса:

enter image description here

A Contact может быть Person или Organisation.

Если вы используете spring-data-mongodb MongoRepository для записи данных в вашу базу данных в соответствии с вашей моделью сущности, поле _class будет добавлено к корням документов и к сложным типам свойств ( см. этот раздел ). В этих полях хранится полное имя класса Java, и это позволяет устранить неоднозначность при отображении из документа MongoDb в модель данных Spring.

Если ваше приложение просто считывает документ из базы данных (без полей _class), вам необходимо указать данным Spring, какой класс создавать при отображении Contact. Spring-data позволяет вам настроить поведение отображения типов по умолчанию, используя Converter. Использование явного Converter переопределения отображения по умолчанию для класса . вам нужно явно отобразить весь ваш класс. Вот пример моего 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;
    }
}

Затем необходимо зарегистрировать вновь определенные преобразователи:

@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);
    }
}

Надеюсь, это поможет.

...