I have a mapper that, for a particular attribute of the target class, needs to choose one from a list of objects inside the source object, and map it using a differente mapper class.
Simplifying it a lot, the Game
class contains a list of Transaction
objects, and my GameMapper
class looks like this:
@Component @Mapper(injectionStrategy = InjectionStrategy.CONSTRUCTOR, uses = {TransactionMapper.class, EventMapper.class}) public interface GameMapper { @Mapping(target = "transaction", expression = "java(transactionMapper.transactionToDto(findTransactionForPlayer(game, idPlayer)))") GameResultDto gameToGameResultDto(Game game, Long idPlayer); // Some more methods }
The thing is, EventMapper
gets generated as a private final EventMapper eventMapper;
attribute inside GameMapperImpl
, but TransactionMapper
is not, so the build fails because MapStruct cannot find transactionMapper
.
My best guess is that this is due to no other methods in GameMapper
using TransactionMapper
explicitly, so Mapstruct decides that it’s not needed and doesn’t inject it in the implementation.
So… is there any way to force MapStruct to include the mappers in the uses
clause, even it if looks like they are not being used, or any other way to work around this?
Advertisement
Answer
My best guess is that this is due to no other methods in
GameMapper
usingTransactionMapper
explicitly, so Mapstruct decides that it’s not needed and doesn’t inject it in the implementation.
That is correct. MapStruct will not inject mappers from Mapper#uses
if they are not used by MapStruct.
What you could do is to use an abstract class.
e.g.
@Mapper(injectionStrategy = InjectionStrategy.CONSTRUCTOR, componentModel = "spring", uses = {TransactionMapper.class, EventMapper.class}) public abstract class GameMapper { @Autowired protected TransactionMapper transactionMapper; @Mapping(target = "transaction", expression = "java(transactionMapper.transactionToDto(findTransactionForPlayer(game, idPlayer)))") public abstract GameResultDto gameToGameResultDto(Game game, Long idPlayer); // Some more methods }