Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Java 8 optional with Mapstruct

Tags:

java

mapstruct

I have these two classes:

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;
}

and

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

The problem is that Mapstruct doesn't recognize the Optional variable "address".

Anyone has an idea how to solve it and let Mapstruct map Optional fields?

like image 972
Ahmed Aziz Avatar asked Oct 09 '19 23:10

Ahmed Aziz


Video Answer


1 Answers

This is not yet supported out of the box by Mapstruct. There is an open ticket on their Github asking for this functionality: https://github.com/mapstruct/mapstruct/issues/674

One way to solve this has been added in the comments of the same ticket: 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);
}

As pointed by @dschulten, if you want to use this workaround while also setting the option nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, you will need to define a method with the signature boolean hasXXX() for the field XXX of type Optional inside the class which is the mapping source (explanation in the docs).

like image 179
Gustavo Passini Avatar answered Sep 27 '22 20:09

Gustavo Passini