Шаблон конструктора при извлечении объекта из БД с реактором весенней загрузки и монго - PullRequest
3 голосов
/ 10 июля 2020

У меня есть следующий bean-компонент, описывающий документ mon go и использующий lombok:

@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder(toBuilder = true)
@Value
public class MyClass {

    private final String id;

    @Default
    private final String field = "defaultValue";

    @JsonPOJOBuilder(withPrefix = "")
    public static class MyClassBuilder {}
}

При десериализации {"id": "document"} с помощью jackson я получаю bean-компонент, содержащий оба id=document и field=defaultValue, потому что он использовал построитель, который предоставляет значение по умолчанию для поля.

Теперь я хочу установить значение defaultValue для документов, исходящих из базы данных (исходящих из ReactiveMongoTemplate). Но, похоже, он использует конструктор all args, даже если я установил его частным (или некоторые отражают black magi c)

Итак, главный вопрос: можно ли указать Spring использовать конструктор для создания bean при выходе из базы?

Ответы [ 2 ]

1 голос
/ 18 июля 2020
  • Вы не сможете использовать свой собственный сериализатор, потому что, когда я go через исходный код MappingMongoConverter в spring mongodb (отлаживал его с помощью образца приложения), я вижу только следующие шаги.

  • Как только значение из db станет доступным как org.bson.Document, MappingMongoConverter.java пытается создать ваш объект entity.

  • Во-первых, он проверяет, есть ли у вас какие-либо зарегистрированные пользовательские преобразователи, и если они у вас есть, то используйте их. Таким образом, один из вариантов - использовать зарегистрированный пользовательский преобразователь.

  • Если пользовательские преобразователи не зарегистрированы, он ищет PersistenceConstructor и использует его. У меня был объект с 3 конструкторами (без параметра, один параметр и все параметры), и он выбрал мой конструктор без параметров.

  • Однако, если я аннотирую конструктор с помощью @PersistenceConstructor, он выбирает этот конструктор. Таким образом, можно использовать этот подход, но тогда вы должны сохранить String field неинициализированными и инициализированными по-разному в каждом конструкторе

  • MappingMongoConverter.java

0 голосов
/ 10 июля 2020

Правильный способ использования Builder с Lombok - использовать следующие аннотации:

@NoArgsConstructor
@AllArgsConstructor
@Builder

Чтобы десериализатор Джексона использовал этот Builder, вам необходимо добавить две аннотации к коду.

  1. Пометка класса аннотацией @JsonDeserialize, передача параметра построителя с полным доменным именем класса построителя - что вы и сделали
  2. Аннотируйте сам класс построителя как @JsonPOJOBuilder

Для Exmaple:

 @JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set")
 public class Builder {
    ...
 }

Использование JsonPOJOBuilder

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...