Search code examples
javalombokmapstruct

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


I have a problem with mapstruct while converting an object to a Long, I have the following warning:

warning: Unmapped target property

Here are the entities (I an using 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;
        ...
    }

and DTOs:

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

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

In addressDTO, I want townId instead of the town object. Here are the mappers:

@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();
    }
}

I wrote a unit test for AddressMapper that works:

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

but it does not work for UserMapper :

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

I have the following warning:

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);

Solution

  • In order to be able to reuse the AddressMapper in the UserMapper you can use Mapping#uses. That way the AddressMapper#addressToAddressDTO method would be detected by MapStruct automatically.

    E.g.

    @Mapper(uses = AddressMapper.class)
    public interface UserMapper {
    
        UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
    
        UserDTO userToUserDTO(User user);
    
    }