带有 BeanMapping#ignoreByDefault=true 和 SubclassMapping 的 MapStruct 映射器不会忽略子类的属性

问题描述 投票:0回答:1

下面是实体到 DTO 映射和映射器以及生成的 Map Struct 实现的示例。


public abstract class User {
    private int id;
    private String firstName;
    private String lastName;
    private int age;
    private LocalDateTime dateOfBirth;
    private List<Address> addresses;
}

public class Address {
    private int userId;
    private String streetAddress;
    private String city;
    private String state;
    private String zipCode;
}

public class Employee extends User {
    private String designation;
    private Employee reportingManager;
}

public class Contractor extends User {
    private String contractingCompanyName;

}

public abstract class UserDTO {
    private int id;
    private String firstName;
    private String lastName;
    private int age;
    private LocalDateTime dateOfBirth;
}

public class EmployeeDTO extends UserDTO {
    private String designation;
    private EmployeeDTO reportingManager;
}

public class ContractorDTO extends UserDTO {
    private String contractingCompanyName;

}

@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION)
public abstract class UserMapper {

    @BeanMapping(ignoreByDefault = true)
    @SubclassMapping(source = Employee.class, target = EmployeeDTO.class)
    @SubclassMapping(source = Contractor.class, target = ContractorDTO.class)
    @Mapping(source = "id", target = "id")
    @Mapping(source = "firstName", target = "firstName")
    @Mapping(source = "lastName", target = "lastName")
    public abstract UserDTO map(User user);
}



生成的映射器

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-07-14T12:56:15-0400",
    comments = "version: 1.5.5.Final, compiler: javac, environment: Java 17.0.5 (Amazon.com Inc.)"
)
public class UserMapperImpl extends UserMapper {

    @Override
    public UserDTO map(User user) {
        if ( user == null ) {
            return null;
        }

        if (user instanceof Employee) {
            return employeeToEmployeeDTO( (Employee) user );
        }
        else if (user instanceof Contractor) {
            return contractorToContractorDTO( (Contractor) user );
        }
        else {
            throw new IllegalArgumentException("Not all subclasses are supported for this mapping. Missing for " + user.getClass());
        }
    }

    protected EmployeeDTO employeeToEmployeeDTO(Employee employee) {
        if ( employee == null ) {
            return null;
        }

        EmployeeDTO employeeDTO = new EmployeeDTO();

        employeeDTO.setId( employee.getId() );
        employeeDTO.setFirstName( employee.getFirstName() );
        employeeDTO.setLastName( employee.getLastName() );
        employeeDTO.setDesignation( employee.getDesignation() );
        employeeDTO.setReportingManager( employeeToEmployeeDTO( employee.getReportingManager() ) );

        return employeeDTO;
    }

    protected ContractorDTO contractorToContractorDTO(Contractor contractor) {
        if ( contractor == null ) {
            return null;
        }

        ContractorDTO contractorDTO = new ContractorDTO();

        contractorDTO.setId( contractor.getId() );
        contractorDTO.setFirstName( contractor.getFirstName() );
        contractorDTO.setLastName( contractor.getLastName() );
        contractorDTO.setContractingCompanyName( contractor.getContractingCompanyName() );

        return contractorDTO;
    }

我预计添加

BeanMapping#ignoreByDefault=true
只会映射显式映射的属性。但子类的情况并非如此。

我希望有一种更好的方法,而不是显式映射每个子类型并使用 InhertConfiguration 进行注释并从子类中排除其他属性。

java mapstruct
1个回答
0
投票

正如MapStruct讨论中提到的,这是MapStruct版本1.5.5中的一个已知错误,并在main中修复(可能在1.6.0版本中)

© www.soinside.com 2019 - 2024. All rights reserved.