What if I need another mapper to create a mapping method implementation?
Since Java interfaces don't allow instance fields (nor should they), my mapper declaration must be an abstract class. However, it didn't help me much.
@Mapper(uses = EmailMapper.class,
componentModel = "spring",
injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public abstract class UserMapper {
private final EmailMapper emailMapper; // another mapper
protected UserMapper(EmailMapper emailMapper) {
this.emailMapper = emailMapper;
}
public User toUser(UpdateUserRequestDto dto) {
User user = new User();
user.setId(dto.getId());
// referencing another mapper
user.setEmailData(emailMapper.toEmailDatas(dto.getEmailData(), user));
return user;
}
}
@Mapper(componentModel = "spring",
injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface EmailMapper {
@Mapping(source = "email", target = "email")
@Mapping(source = "user", target = "user")
EmailData toEmailData(String email, User user);
default List<EmailData> toEmailDatas(List<String> emails, User user) {
List<EmailData> emailData = emails.stream()
.map(e -> toEmailData(e, user))
.toList();
return emailData;
}
}
Here's what MapStruct generated:
@Component
public class UserMapperImpl extends UserMapper {
private final EmailMapper emailMapper;
@Autowired
public UserMapperImpl(EmailMapper emailMapper) {
this.emailMapper = emailMapper;
}
It declared its own field instead of passing the mapper to super()
as I intended.
So how do I reference other mappers in my mapping method implementations?
One solution is to declare the dependency mapper using setter instead of constructor.
If you are using Lombok, you can write it like this:
@Mapper(componentModel = "spring")
public abstract class UserMapper {
@Setter(onMethod_ = @Autowired)
private EmailMapper emailMapper; // another mapper
...
}
Or, without Lombok:
@Mapper(componentModel = "spring")
public abstract class UserMapper {
private EmailMapper emailMapper; // another mapper
@Autowired
public void setEmailMapper(EmailMapper emailMapper) {
this.emailMapper = emailMapper;
}
...
}