Как преобразовать из String в enum во время BeanUtils.copyProperties в API Spring Boot Rest

Мне нужно скопировать свойства из dto в класс сущности. Я использую BeanUtils.copyProperties().

В теле запроса я отправляю, как показано ниже:

{
"userName":"test",
"userStatus": "I",
}

Класс ДТО:

public class UserDto {
    private String userName;
    private String userStatus;

    public User buildUser() {
        User user = new User();
        BeanUtils.copyProperties(this, user);

        return user;
    }
}

Класс сущности:

public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long userId;

    @Column(name = "user_name")
    private String userName;

    @Enumerated(EnumType.STRING)
    @Column(name = "user_status")
    private UserStatus userStatus;

}

Заметка: userStatus может быть пустым полем в таблице.

Код услуги:

User user = userDto.buildUser();

Я получаю значение userStatus как нулевое в классе сущности пользователя.

Когда я изменил UserDto.userStatus на тип перечисления, тело запроса не принимает пустое значение.

Как мне преобразовать из String в enum во время BeanUtils.copyProperties()?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
2 599
2

Ответы 2

Перечисления не могут быть null, потому что их значения подчеркивания — int, но вы можете установить ПЕРВОЕ значение в enum как значение по умолчанию. Вы также можете определить свое поле в DTO как тип Enum вместо String.

Статус пользователя

public enum UserStatus {
    NULL,
    ACTIVE,
    INACTIVE;

}

Код услуги:

userDto.setUserStatus(UserStatus.NULL);
userDto.buildUser();

ИЛИ Если вы хотите, чтобы это переопределение метода copyProperties игнорировало поле userStatus при преобразовании:

 public static void copyProperties(Object source, Object target,
                                   @Nullable Class<?> editable,
                                   @Nullable String... ignoreProperties); 

Если я проигнорирую поле, как оно будет преобразовано в значение перечисления?

Krish 21.01.2019 13:46

Spring BeanUtils не предназначен для таких настроек.
Вы должны установить поле вручную с помощью .
В то время как MapStruct или Dozen есть.

В качестве альтернативы сохранению BeanUtils и отсутствию явного вызова установщика у вас есть:

  • определение фабричного метода для обработки перечисления Джексона (статический метод, аннотированный @JsonCreator в классе перечисления, например:

@JsonCreator public static UserStatus getValue(String name) {
return Stream.of(UserStatus.values()) .findAny(s -> s.name().equals(name)) .orElse(null); }

В большинстве случаев это лучшее решение, поскольку оно решает проблему в корне.

  • установка флага игнорирования неизвестного значения для любого поля класса:

public class UserDto { @JsonIgnoreProperties(ignoreUnknown = true) //... }

Самое быстрое решение, но мне многое не нравится, поскольку оно может скрывать некоторые другие проблемы с сериализацией/десериализацией.

  • добавление значения перечисления, представляющего пустоту. Вы можете определить перечисление в DTO.
    . Чтобы не хранить его в базе данных, сопоставление этого значения перечисления с null должно выполняться в самой сущности.
    Например :

public void setUserStatus(UserStatus userStatus){ if (userStatus != UserStatus.EMPTY){ this.userStatus = userStatus; } }

Должно сработать, но я тоже не фанат...

Другие вопросы по теме