将对象转换为 Long 时使用 mapstruct 未映射目标 属性

Unmapped target property with mapstruct while converting an object to a Long

我在将对象转换为 Long 时遇到 mapstruct 问题,我收到以下警告:

warning: Unmapped target property

以下是实体(我使用的是 Lombok):

    @Getter
    @Setter
    @NoArgsConstructor
    @Entity
    public class User {
        ...
        private Set<Address> addresses= new HashSet<>();
        ...
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @Entity
    public class Address {
        ...
        private Town town;
        ...
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @Entity
    public class Town {
        ...
        private Long id;
        ...
    }

和 DTO:

    @Getter
    @Setter
    @NoArgsConstructor
    public class UserDTO {
        ...
        private Set<AddressDTO> addresses= new HashSet<>();
        ...
    }

    @Getter
    @Setter
    @NoArgsConstructor
    public class AddressDTO {
        ...
        private Long townId;
        ...
    }

在 addressDTO 中,我想要 townId 而不是 town 对象。以下是映射器:

@Mapper
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDTO userToUserDTO(User user);

}

@Mapper
public interface AddressMapper {

    AddressMapper INSTANCE = Mappers.getMapper(AddressMapper.class);

    @Mapping(target = "townId", source = "town")
    AddressDTO addressToAddressDTO(Address address);

    default Long getTownId(Town town) {
        return town.getId();
    }
}

我为 AddressMapper 编写了一个有效的单元测试:

AddressDTO addressDTO = AddressMapper.INSTANCE.addressToAddresslDTO( address);

但它不适用于 UserMapper :

UserDTO userDTO = userMapper.INSTANCE.userToUserDTO( user);

我有以下警告:

warning: Unmapped target property: "townId". Mapping from Collection element "fr.example.myproj.entity.Adress adresses" to "fr.example.myproj.service.dto.AdressDTO adresses".
    UserDTO userToUserDTO(User user);

我找到了使用 custom method to mapper 的解决方案。

@Mapper
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDTO userToUserDTO(User user);

    default AddressDTO addressToAddressDTO(Address address) {
        return AddressMapper.INSTANCE.addressToAdressDTO( address );
    }

}

为了能够在 UserMapper 中重复使用 AddressMapper,您可以使用 Mapping#uses。这样 AddressMapper#addressToAddressDTO 方法将被 MapStruct 自动检测到。

例如

@Mapper(uses = AddressMapper.class)
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDTO userToUserDTO(User user);

}