Reputation: 427
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?
Upvotes: 10
Views: 19265
Reputation: 89
New solution: return repository.findById(id).map(entity -> mapper.toDTO(entity));
Older solution: People seem to have problem after upgrading from mapstruct 1.3.1 to higher version, so the new workaround would be:
@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;
}
expecting you have imported the mapper, you can use it something like this:
Optional.ofNullable(kidMapper.toKidDTO(KidMapper.unwrapReference(kidRepository.findById(chatId))));
answered by janinko in this issue: https://github.com/mapstruct/mapstruct/issues/2295
Upvotes: 1
Reputation: 2668
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).
Upvotes: 17