Мне нужно скопировать свойства из 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()?




Перечисления не могут быть 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);
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)
//...
}
Самое быстрое решение, но мне многое не нравится, поскольку оно может скрывать некоторые другие проблемы с сериализацией/десериализацией.
null должно выполняться в самой сущности.public void setUserStatus(UserStatus userStatus){
if (userStatus != UserStatus.EMPTY){
this.userStatus = userStatus;
}
}
Должно сработать, но я тоже не фанат...
Если я проигнорирую поле, как оно будет преобразовано в значение перечисления?