Mapstruct works fine in project but there is a problem with @Mapping annotation.
Working Spring Boot version 2.2.0.RELEASE
Here is dependency details :
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.mapstruct:mapstruct'
annotationProcessor 'org.mapstruct:mapstruct-processor'
implementation 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0"
Here is example about the problem.
UserEntity.java
public class UserEntity {
private String username;
private Integer userAge;
private UserAddressEntity userAddressEntity;
}
UserAddressEntity.java
public class UserAddressEntity {
private String userAddress;
private Integer userPhone;
}
UserAddressDTO
public class UserAddressDTO {
private String userAddress;
private Integer userPhone;
}
TargetDTO (I want to convert UserEntity to this DTO)
public class TargetDTO {
private String username;
private Integer userAge;
private UserAddressDTO userAddressDto;
}
Here is mapper class :
@Mapper(componentModel = "spring")
public interface UserEntityMapper {
@Mapping(source = "userAddressEntity", target = "userAddressDto")
List<TargetDTO> fromEntityToDto(List<UserEntity> userEntityList);
}
In this interface, Mapstruct can not create implementation for @Mapping. I changed implemenetation like this:
@Mapper(componentModel = "spring")
public interface UserEntityMapper {
@Mapping(source = "userAddressEntity.userAddress", target = "userAddressDto.userAddress")
@Mapping(source = "userAddressEntity.userPhone", target = "userAddressDto.userPhone")
List<TargetDTO> fromEntityToDto(List<UserEntity> userEntityList);
}
It is still not working.
All other fields are mapping successfully only the definition in @Mapping is not working.
But, when I removed @Mapping and I changed TargetDto like this, it works :
public class TargetDTO {
private String username;
private Integer userAge;
private UserAddressDTO userAddressEntity; // I just updated property naming
}
But why is it not working with @Mapping. This is the problem.
Also I tried "uses" definition and seperated problematic mapper but it also could not map UserAddressEntity to UserAddressDTO :
@Mapper(componentModel = "spring", **uses = UserAddressMapper.class**)
public interface UserEntityMapper {
@Mapping(source = "userAddressEntity", target = "userAddressDto")
List<TargetDTO> fromEntityToDto(List<UserEntity> userEntityList);
}
What is the problem with @Mapping usage? When code is compiling Mapstruct can create Implementation class and build implementation code for all other fields but it can not create implementation code for @Mapping in the Implementation class. I tried many ways and it does not work in anyway.
@Mapping
is not directly applicable to methods for mapping collections. Instead, you should define a mapping method for individual objects.
@Mapper(componentModel = "spring")
public interface UserEntityMapper {
@Mapping(source = "userAddressEntity", target = "userAddressDto")
TargetDTO fromEntityToDto(UserEntity userEntityList);
List<TargetDTO> fromEntitiesToDtos(List<UserEntity> userEntityList);
}
MapStruct will invoke the fromEntityToDto
method for each element when performing collection mapping.