Как отключить сопоставление полей для документов Spring Data MongoDB?

Я использую Spring Data для сохранения POJO в виде документов в MongoDB через MongoRepository. Похоже, что Spring автоматически сохраняет как поля, так и геттеры в MongoDB.

В общем, я бы хотел, чтобы сохранялись только геттеры и никогда автоматически не сохранялись поля. Я знаю о @Transient для одноразовых аннотаций, но хотел бы настроить это как общее поведение.

Есть ли способ настроить это?


person DanJ    schedule 29.09.2015    source источник
comment
Вы пытались аннотировать геттер как временный и сделать поле приватным? Это должно работать (хотя это и нелогично), если реализован аналог JPA.   -  person Markus W Mahlberg    schedule 29.09.2015
comment
Вообще говоря, все мои поля являются частными, и все они сохраняются. Я могу пометить сами частные поля как @Transient, и это не позволит им сохраниться. Однако POJO, которые я переношу в MongoDB, как правило, должны сохранять данные только из своих геттеров, а приватное поле не предназначено для сохранения. Что еще хуже, я периодически сталкиваюсь с конфликтами полей, когда один класс наследует другой, а приватное поле имеет то же имя, что и общедоступный геттер в суперклассе.   -  person DanJ    schedule 29.09.2015
comment
Вот почему я заявил, что может помочь аннотирование геттера вместо частного поля... Или я здесь что-то не так...   -  person Markus W Mahlberg    schedule 30.09.2015
comment
Ха, я не уверен. Вы сказали, что это может быть нелогичным, поэтому, возможно, я что-то упускаю. Я понимаю, что если я отмечу геттер как Transient, он не сохранит результаты геттера, что противоположно тому, что я хочу. Но в любом случае я ищу параметр конфигурации на системном уровне или даже на уровне класса, который заставляет Spring игнорировать все члены поля при сохранении. В противном случае кажется, что мне нужно зайти во весь мой класс и явно пометить все переменные-члены как Transient. Кажется неправильным/инвазивным??   -  person DanJ    schedule 30.09.2015
comment
Спасибо за помощь, Маркус. Похоже, у меня была обратная концепция доступа к Spring Data (см. Комментарии Конрада ниже). Он смотрит только на поля, а не на геттеры. Кажется, я понимаю, что сейчас происходит и почему я был сбит с толку, спасибо.   -  person DanJ    schedule 30.09.2015


Ответы (1)


Это можно сделать, написав свои собственные преобразователи.

В своем вопросе вы указываете, что весенние данные mongodb сохраняются оба, поля и геттеры. Насколько мне известно, сохраняются только поля. (См. 11.1 в документе: http://docs.spring.io/spring-data/mongodb/docs/1.6.3.RELEASE/reference/html/#mapping-conventions (1.6.3 — версия, поставляемая spring-boot 1.2 .6, но он же и в старых версиях и в 1.8.0))

или короткий пример:

Если у вас есть Pojo, как это:

@Document
public class MyClass
{
    private ObjectId id;

    private String foo = "foo";

    public String getBar()
    {
        return "bar";
    }
}

и такой репозиторий:

public interface MyClassRepository extends MongoRepository<MyClass,ObjectId>
{
}

и такой код приложения:

public static void main(String[] args) throws UnknownHostException
{
    ApplicationContext ctx = SpringApplication.run(NewClass.class, args);
    MongoTemplate mongoTemplate = ctx.getBean(MongoTemplate.class);
    MyClass myClass = new MyClass();
    mongoTemplate.save(myClass);
    MyClassRepository myClassRepository = ctx.getBean(MyClassRepository.class);
    myClassRepository.save(myClass);
}

следующий документ сохраняется (один раз по шаблону, а затем снова по репозиторию):

{
    "_id" : ObjectId("560b97edcb60110890ab7119"),
    "_class" : "sandbox.MyClass",
    "foo" : "foo"
}

Таким образом, геттер не использовался для преобразования объекта MyClass.

В той же документации, что и выше, показано, как написать собственный конвертер и как зарегистрировать его в шаблоне MongoTemplate (раздел 8.10). Вы можете написать здесь некоторый код, который использует объявленные геттеры вашего класса и сопоставляет их с полями вашего документа.

person Konrad Lötzsch    schedule 30.09.2015
comment
Ах, вы правы. В Hibernate мы всегда используем только режим свойств и отключаем средства доступа к полям. Итак, я думал об этом в обратном направлении в отношении данных Spring, что было источником моей путаницы. Интересно... Хорошо, спасибо за помощь! - person DanJ; 30.09.2015