Mapstruct - compilation failure when mapping DTOs that extend from base class

Viewed 488

I'm trying to map this:

public class UserInfoDTO {
    private String addressDto;
}
public class B extends UserInfoDTO {
    private String roleId;
}
public class A extends UserInfoDTO {
    private String groupId;
}

from:

public class Entity {
    private Address address;
}

Address contains some fields and "String city" field.

I want to map between the Entity and the DTOs

@Mapper(componentModel = "jsr330")
public interface IUserMapper {
   A aFromEntity (Entity entity); 
   B bFromEntity (Entity entity); 
   
   @Mappings({
            @Mapping(target = "addressDto", source = "entity.address.city")
   })
   UserInfoDTO fromEntity (Entity entity); 
}

But I get a compilation failure that "can't map property Address address to String addressDto". Please help :)

1 Answers

You need to add getters and setters to your classes:

The general philosophy of MapStruct is to generate code which looks as much as possible as if you had written it yourself from hand. In particular this means that the values are copied from source to target by plain getter/setter invocations instead of reflection or similar.

MapStruct 1.4.1.Final Reference Guide

UPDATE. If instead of getters/setters you use Lombok.

Don't forget about annotationProcessorPaths during the compile time, so the Lombok could generate getters and setters.

Maven example:

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>                        
                        <annotationProcessorPaths>
                            <path>
                                <groupId>org.mapstruct</groupId>
                                <artifactId>mapstruct-processor</artifactId>
                                <version>${org.mapstruct.version}</version>
                            </path>
                            <path>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                                <version>${org.projectlombok.version}</version>
                            </path>
                            <path>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok-mapstruct-binding</artifactId>
                                <version>${lombok-mapstruct-binding.version}</version>
                            </path>
                        </annotationProcessorPaths>
                    </configuration>
                </plugin>       
            </plugins>
        </pluginManagement>
    </build>

Gradle example

dependencies {
   // Lombok
   compileOnly 'org.projectlombok:lombok:1.18.2'
   annotationProcessor 'org.projectlombok:lombok:1.18.2'

   // MapStruct
   compileOnly 'org.mapstruct:mapstruct-jdk8:1.2.0.Final'
   annotationProcessor 'org.mapstruct:mapstruct-processor:1.2.0.Final'

}
Related