I have two MapStruct Mapping classes for the same Bird entity, with Methods (customCodeBirdMapping) that do almost the same thing but have slightly different return types.
BirdViewMapper
@Mapper(componentModel = "spring")
public interface BirdViewMapper {
@Mapping(source = "bird.listHealthCheck", target = "listHealthCheck")
BirdViewDTO birdToBirdViewDTO(Bird bird);
@AfterMapping
default void customCodeBirdMapping(Bird source, @MappingTarget BirdViewDTO target) {
if (!source.getListTransmitter().isEmpty()) {
Transmitter trans = (source.getListTransmitter()
.stream()
.max(Comparator.comparing(Transmitter::getDateAttached)).get());
target.setChannel(trans.getChannel());
target.setChannelOffset(trans.getChannelOffset());
}
if (!source.getListPIT().isEmpty()) {
PIT pit = (source.getListPIT()
.stream()
.max(Comparator.comparing(PIT::getDateInserted)).get());
target.setPitCode(pit.getCode());
}
if (!source.getListHealthCheck().isEmpty()) {
HealthCheck healthCheck = (source.getListHealthCheck()
.stream()
.max(Comparator.comparing(HealthCheck::getCatchDate)).get());
target.setDateLastHealthCheck(healthCheck.getCatchDate());
}
}
}
BirdMapper
@Mapper(componentModel = "spring")
public interface BirdMapper {
BirdDashboardDTO birdToBirdListDTO(Bird bird);
@AfterMapping
default void customCodeBirdMapping(Bird source, @MappingTarget BirdDashboardDTO target) {
if (!source.getListTransmitter().isEmpty()) {
Transmitter trans = (source.getListTransmitter()
.stream()
.max(Comparator.comparing(Transmitter::getDateAttached)).get());
target.setChannel(trans.getChannel());
target.setChannelOffset(trans.getChannelOffset());
}
if (!source.getListPIT().isEmpty()) {
PIT pit = (source.getListPIT()
.stream()
.max(Comparator.comparing(PIT::getDateInserted)).get());
target.setPitCode(pit.getCode());
}
if (!source.getListHealthCheck().isEmpty()) {
HealthCheck healthCheck = (source.getListHealthCheck()
.stream()
.max(Comparator.comparing(HealthCheck::getCatchDate)).get());
target.setDateLastHealthCheck(healthCheck.getCatchDate());
}
}
}
Notice that both BirdViewMapper and BirdMapper use an @AfterMapping
to set the most recent value of some child entities but the return/target types are different.
The Bird DTOs are for different views, one for a list of birds (only a few fields) one for a view of a single bird many fields.
I am breaking the DRY rule with the customCodeBirdMapping
method on my mapper classes - is there a better way - a way to avoid the repetition?