javamodelmapper

ModelMapper, mapping list of Entites to List of DTO objects


I am writing simple blog web application using Spring MVC framework. I am willing to add DTO layer to my app.

I decided to use ModelMapper framework for conversion from Entity objects to DTO objects used in my views.

I have just one problem. On my main page, I am showing a list of posts on my blog. In my view, it's just list of Post (Entity) objects. I want to change it to pass a list of PostDTO objects to my view. Is there any way to map List of Post objects to List of PostDTO object with single method call? I was thinking about writing converter that will convert this but I am not sure it's a good way to do it.

Also, I am using Lists of Entities in few more places like administrative panel or comment below every Post on my page.

Link to code of my app on GitHub repository: repository


Solution

  • You can create util class:

    public class ObjectMapperUtils {
    
        private static final ModelMapper modelMapper;
    
        /**
         * Model mapper property setting are specified in the following block.
         * Default property matching strategy is set to Strict see {@link MatchingStrategies}
         * Custom mappings are added using {@link ModelMapper#addMappings(PropertyMap)}
         */
        static {
            modelMapper = new ModelMapper();
            modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        }
    
        /**
         * Hide from public usage.
         */
        private ObjectMapperUtils() {
        }
    
        /**
         * <p>Note: outClass object must have default constructor with no arguments</p>
         *
         * @param <D>      type of result object.
         * @param <T>      type of source object to map from.
         * @param entity   entity that needs to be mapped.
         * @param outClass class of result object.
         * @return new object of <code>outClass</code> type.
         */
        public static <D, T> D map(final T entity, Class<D> outClass) {
            return modelMapper.map(entity, outClass);
        }
    
        /**
         * <p>Note: outClass object must have default constructor with no arguments</p>
         *
         * @param entityList list of entities that needs to be mapped
         * @param outCLass   class of result list element
         * @param <D>        type of objects in result list
         * @param <T>        type of entity in <code>entityList</code>
         * @return list of mapped object with <code><D></code> type.
         */
        public static <D, T> List<D> mapAll(final Collection<T> entityList, Class<D> outCLass) {
            return entityList.stream()
                    .map(entity -> map(entity, outCLass))
                    .collect(Collectors.toList());
        }
    
        /**
         * Maps {@code source} to {@code destination}.
         *
         * @param source      object to map from
         * @param destination object to map to
         */
        public static <S, D> D map(final S source, D destination) {
            modelMapper.map(source, destination);
            return destination;
        }
    }
    

    And use it for your needs:

    List<PostDTO> listOfPostDTO = ObjectMapperUtils.mapAll(listOfPosts, PostDTO.class);