2

I understand Mapstruct allows me to define my own mapper logic, I am doing it like this:

@Mapper(componentModel = "spring")
public abstract class ProjectMapper {

    public ProjectInfo map(ProjectEntity projectEntity) {
        ProjectInfo projectInfo = new ProjectInfo();
        projectInfo.setName(projectEntity.getName());
        projectInfo.setDescription(projectEntity.getDescription());

        // Specific logic that forces me to define it myself
        if (projectEntity.getId() != null) {
            projectInfo.setId(projectEntity.getId());
        }
        if (projectEntity.getOrganisation() != null) {
            projectInfo.setOrganisation(projectEntity.getOrganisation().getName());
        }
        return projectInfo;
    }
}

It works just fine, but I also want Mapstruct's generated mappers, but they have to be defined in an interface, is there a way to group up both of these mapper types?

Christopher
  • 1,712
  • 2
  • 21
  • 50
  • What do you mean by `MapStruct`s mapper have to be defined in an interface? You can also define theme in an `abstract` class, `MapStruct` will implement all the abstract methods. I am not sure if your specific logic is really like it looks like, but `MapStruct` can generate the exact same method. – Filip Jun 08 '17 at 16:22

1 Answers1

0

NOTE: Untested. I used the following solution once in a Spring-Boot project using MapStruct version 1.0.0.Final.

Customizing standard mapping process is fairly well documented.

One of the way to customize your mappings are 'AfterMapping' and 'BeforeMapping' hooks:

@Mapper
public abstract class ProjectMapperExtension {

    @AfterMapping
    public void mapProjectEntityToProjectInfo(ProjectEntity projectEntity, @MappingTarget ProjectInfo projectInfo) {

        if (projectEntity.getId() != null) {
            projectInfo.setId(projectEntity.getId());
        }

        if (projectEntity.getOrganisation() != null) {
            projectInfo.setOrganisation(projectEntity.getOrganisation().getName());
        }
    }
}

Then annotate the standard mapper interface with uses and exclude the custom mapped fields from the standard mapping:

@Mapper(componentModel = "spring", uses = {ProjectMapperExtension.class})
public interface ProjectMapper {

    @Mapping(target = "id", ignore = true)
    @Mapping(target = "organisation", ignore = true)
    ProjectInfo mapProjectEntityToProjectInfo(ProjectEntity projectEntity);
}
jannis
  • 4,843
  • 1
  • 23
  • 53