Search code examples
javaspring-bootmodelmapper

ModelMapper propertyMap with List of objects to a responseDTO


I'm new to modelMapper and I've encountered a problem when I tried to List of entity objects to a responseDTO.

User - Entity UserResponseDTO - response DTO

I did the following configurating for propertyMap.

        modelMapper.addMappings(new PropertyMap<List<User>, UserResponseDTO>() {
            @Override
            protected void configure() {
                map().setName(source.get(0).getName());
                map().setEmail(source.get(0).getEmail());
                map().setUserRole(source.get(0).getUserRole());
                map().setLanguage(source.get(0).getLanguage());
                map().setTimeZone(source.get(0).getTimeZone());
                // ....have more mapping ahead
            }
        });

But it gives following errors:

org.modelmapper.ConfigurationException: ModelMapper configuration errors:

1) Invalid source method java.util.List.get(). Ensure that method has zero parameters and does not return void.

2) Invalid source method java.util.List.get(). Ensure that method has zero parameters and does not return void.

3) Invalid source method java.util.List.get(). Ensure that method has zero parameters and does not return void.

4) Invalid source method java.util.List.get(). Ensure that method has zero parameters and does not return void.

5) Invalid source method java.util.List.get(). Ensure that method has zero parameters and does not return void.

Can anyone tell me how can I fix this issue?


Solution

  • It is exactly as the error message says:

    Ensure that method has zero parameters

    This is because (below excerpt from here)

    You receive these errors because PropertyMap restricts what you can do inside configure().

    I find it hard to understand what you actually are trying to map because it seems that you just want to flatten some list of Users to a DTO containing data from a just a single user, namely the first in the list (if not empty!). Maybe you are not doing what you should or maybe you do it on a wrong manner. At least it seems that you do not need any special mappings.

    Assuming your User and UserResponseDTO would be like (simplified!) :

    @Getter @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
        private Long id;
        private String name;
        private String email;
    }
    

    and

    @Getter
    @Setter
    public class UserResponseDTO {
        private String name;
        private String email;
    }
    

    then mapping single user would be like:

    new ModelMapper().map(users.get(0), UserResponseDTO.class);
    

    and if you would like to map the who list, like:

    new ModelMapper().map(users, UserListResponseDTO.class)
    

    then your UserListResponseDTO would simply be something like:

    @SuppressWarnings("serial")
    public class UserListResponseDTO extends ArrayList<UserResponseDTO> {}
    

    or if it happens that you need to return a list with just the first user:

    new ModelMapper()..map(Arrays.asList(users.get(0)), UserListResponseDTO.class)