将Java 8可选与Mapstruct配合使用

mspsb9vt  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(161)

我有这两个类:

public class CustomerEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String firstName;
    private String lastName;
    private String address;
    private int age;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

public class CustomerDto {
    private Long customerId;
    private String firstName;
    private String lastName;
    private Optional<String> address;
    private int age;
}

问题是Mapstruct不能识别Optional变量“address”。
有人知道如何解决它,让MapstructMap可选字段吗?

h43kikqp

h43kikqp1#

Mapstruct还不支持开箱即用。在他们的Github上有一个开放的ticket要求此功能:https://github.com/mapstruct/mapstruct/issues/674
解决这个问题的一种方法已经在同一张票的评论中添加了:https://github.com/mapstruct/mapstruct/issues/674#issuecomment-378212135

@Mapping(source = "child", target = "kid", qualifiedByName = "unwrap")
Target map(Source source);

@Named("unwrap")
default <T> T unwrap(Optional<T> optional) {
    return optional.orElse(null);
}

正如@dschulten所指出的,如果你想在设置nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS选项的同时使用这个解决方案,你需要在作为Map源的类中为Optional类型的字段XXX定义一个签名为boolean hasXXX()的方法(在文档中有解释)。

fzwojiic

fzwojiic2#

新解决方案:return repository.findById(id).map(entity -> mapper.toDTO(entity));
较旧的解决方案:从mapstruct 1.3.1升级到更高版本后,人们似乎遇到了问题。因此,新的解决方法是:

@Mapping(source = "child", target = "kid")
Target map(Source source);

    @Reference
    public static <T> T unwrapReference(Optional<T> optional) {
        return (optional != null && optional.isPresent()) ? optional.get() : null;
    }

期望你已经导入了Map器,你可以像这样使用它:
Optional.ofNullable(kidMapper.toKidDTO(KidMapper.unwrapReference(kidRepository.findById(chatId))));
janinko在这个问题上回答:https://github.com/mapstruct/mapstruct/issues/2295

相关问题