Предотвратить нулевую проверку в Mapstruct при обновлении - PullRequest
0 голосов
/ 04 января 2019

Я борюсь с обновлением формы.Пожалуйста, рассмотрите этот пример:

// Entity with which I need to perform CRUD operations
public class User {
    private String name;
    private String email;
    private String phone;
    private String address;
}

Я отправляю в пользовательский интерфейс UserDTO:

public class UserDTO {
    private String name;
    private ContactDataDTO contactDataDTO;
}

public class ContactDataDTO {
    private String email;
    private String phone;
    private String address;
}

Мой маппер:

@Mapper
public interface UserMapper {

    @Mappings({
        @Mapping(source="email", target="contactDataDTO.email"),
        @Mapping(source="phone", target="contactDataDTO.phone"),
        @Mapping(source="address", target="contactDataDTO.address")
    })
    UserDTO userToUserDTO(User user);

    @InheritInverseConfiguration
    User updateUserFromUserDTO(UserDTO userDTO, @MappingTarget User user);

}

userToUserDTO () работает как положено, носгенерированный userDTOToUser () для меня кажется странным:

@Override
public User updateUserFromUserDTO(UserDTO userDTO, User user) {
    if ( userDTO == null ) {
        return null;
    }

    String address = userDTOContactDataDTOAddress( userDTO );
    if ( address != null ) {
        user.setAddress( address );
    }
    String phone = userDTOContactDataDTOPhone( userDTO );
    if ( phone != null ) {
        user.setPhone( phone );
    }
    String email = userDTOContactDataDTOEmail( userDTO );
    if ( email != null ) {
        user.setEmail( email );
    }
    user.setName( userDTO.getName() );

    return user;
}

Проблемный вариант использования:

  1. Заполните все поля для пользователя.
  2. Снова откройте формуи очистить поле телефона.
  3. Это означает, что для бэкенда я отправлю что-то вроде этого:

userDTO: {
        name: 'John Doe';
        contactDataDTO: {
            email: 'johndoe@gmail.com',
            phone: null,
            address: 'Home'
        }
    }

Итак, user.phone не будет обновляться, насколько это возможно.поскольку у меня есть нулевая проверка для этого в генерируемом коде


Я думал, что NullValueCheckStrategy - это то, что мне нужно, но нет варианта, который подходит мне.На данный момент единственный вариант, который я вижу, - написать свою собственную реализацию userDTOToUser () без нулевых проверок.Может быть, вы можете посоветовать лучшее решение, потому что для меня это выглядит как проблема, которая может возникнуть в любом картографе для целевого обновления из DTO с не примитивным источником.

Runnable demo: https://repl.it/@aksankin/SlateblueUnimportantStack

Большое спасибо.

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Если вы хотите, чтобы null имел для вас определенное значение, тогда вы ищете проверку присутствия источника .Затем вы можете контролировать в setPhone DTO, был ли он установлен или нет, и добавить hasPhone, который будет использовать флаг.Тогда MapStruct будет использовать метод проверки присутствия при установке значения.

0 голосов
/ 07 января 2019

попробовать:

@Mapper(  )
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper( UserMapper.class );

    @Mappings({
        @Mapping(source="email", target="contactDataDTO.email"),
        @Mapping(source="phone", target="contactDataDTO.phone"),
        @Mapping(source="address", target="contactDataDTO.address")
    })
    UserDTO userToUserDTO(User user);

    default void updateUserFromUserDTO(UserDTO userDTO, User user) {
        intUpdateUserFromUserDTO( userDTO, userDTO.getContactDataDTO(), user );
    }

    void intUpdateUserFromUserDTO(UserDTO userDTO, ContactDataDTO contactDataDTO, @MappingTarget User user);

}

(примечание: я вернул void iso a type, который строго не нужен).

0 голосов
/ 04 января 2019

Возможно, опционально <> - это то, что вы ищете. В этом случае у вас будет нулевое значение для пустого поля, необязательное, если нулевое значение было отправлено из пользовательского интерфейса, и необязательное для фактического значения. Но, вероятно, вам нужно создать другое DTO для запроса и ответа.

...