Search code examples
javamodelmapper

map 2 collection types using modelmapper


I am developing and spring application and for object mapping I am using ModelMapper library.

I am able to map basic class mapping but when I am trying to map 2 collection elements, source is set of enumeration with additional property like name and description and destination is pojo having id, name and description.

I have tried typemap and converters in mapping profile but I am getting exception of mapper.

And the source class is from other application(whose dependency have been added in pom.xml). I also don't want source type as an argument in setter of destination.

Ex.

SOURCE:

public class VType{

   private int id;
   private String name;
   private String description;

}

public class VDTO{

   private Set<VType> vTypes;

   public Set<VType> getVTypes(){
       return this.vTypes;
   }

   public void setVType() { //here I don't want to pass source type as an argument
     //code stuff that I don't know what to do here
   }
}

SOURCE ENUM:

public enum SourceVType{
   V1(1, "Name1", "Desc1");
   V2(2, "Name2", "Desc2");


   private Integer id;
   private String name;
   private String description;


   SourceVType(Integer id, String name, String description) {
       this.id = id;
       this.name = name;
       this.description = description;
   }

   //getter-setter
}

Solution

  • Have you tried converter feature of modelmapper. You can use typemap converter to achieve this requirement.

    @RunWith(JUnit4.class)
    public class TempTest {
    
        @Test
        public void TestThis(){
    
            final ModelMapper mapper = new ModelMapper();
            mapper.addMappings(new PropertyMap<SrcClass, DestClass>() {
                @Override
                protected void configure() {
                    this.map().setId(this.source.getId());
                    this.map().setName(this.source.getName());
                    mapper.createTypeMap(TypeEnum.class, TypeClass.class).setConverter(
                            new Converter<TypeEnum, TypeClass>() {
                                @Override
                                public TypeClass convert(MappingContext<TypeEnum, TypeClass> mappingContext) {
                                    if (mappingContext.getSource() == null) {
                                        return null;
                                    }
                                    TypeEnum typeEnum = mappingContext.getSource();
    
                                    TypeClass typeClass = new TypeClass();
                                    typeClass.setId(typeEnum.getId());
                                    typeClass.setName(typeEnum.getName());
                                    return typeClass;
                                }
                            });
    
                }
            });
    
            SrcClass srcObj = new SrcClass();
            srcObj.setId(1);
            srcObj.setName("name");
            srcObj.setTypes(new HashSet<>(Arrays.asList(TypeEnum.TYPE1, TypeEnum.TYPE2)));
    
            DestClass dstObj = mapper.map(srcObj, DestClass.class);
    
            Assert.assertEquals(srcObj.getId(), dstObj.getId());
            Assert.assertEquals(srcObj.getName(), dstObj.getName());
            Assert.assertEquals(srcObj.getTypes().size(), dstObj.getTypes().size());
    
            for(TypeClass c : dstObj.getTypes()) {
                TypeEnum e = TypeEnum.getById(c.getId());
                Assert.assertNotNull(e);
                Assert.assertTrue(srcObj.getTypes().contains(e));
            }
        }
    
        public static <Source, Result> Set<Result> convertAll(Set<Source> source, Function<Source, Result> projection)
        {
            Set<Result> results = new HashSet<>();
    
            if(source == null) return results;
    
            for (Source element : source)
            {
                results.add(projection.apply(element));
            }
    
            return results;
        }
    
        public static class SrcClass{
            private Integer id;
            private String name;
    
            private Set<TypeEnum> types;
    
            public Integer getId() {
                return id;
            }
    
            public void setId(Integer id) {
                this.id = id;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public Set<TypeEnum> getTypes() {
                return types;
            }
    
            public void setTypes(Set<TypeEnum> types) {
                this.types = types;
            }
        }
    
        public static class DestClass{
            private Integer id;
            private String name;
    
            private Set<TypeClass> types;
    
            public Integer getId() {
                return id;
            }
    
            public void setId(Integer id) {
                this.id = id;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public Set<TypeClass> getTypes() {
                return types;
            }
    
            public void setTypes(Set<TypeClass> types) {
                this.types = types;
            }
        }
    
        public static enum TypeEnum{
    
            TYPE1(1, "Type 1")
            , TYPE2(2, "Type 2")
            , TYPE3(3, "Type 3")
            , TYPE4(4, "Type 4");
    
            private Integer id;
            private String name;
    
            TypeEnum(Integer id, String name) {
                this.id = id;
                this.name = name;
            }
    
    
            private static final Map<Integer, TypeEnum> byId = new HashMap<>();
            private static final Map<String, TypeEnum> byName = new HashMap<>();
    
            static {
                for (TypeEnum e : TypeEnum.values()) {
                    if (byId.put(e.getId(), e) != null) {
                        throw new IllegalArgumentException("duplicate id: " + e.getId());
                    }
    
                    if (byName.put(e.getName(), e) != null) {
                        throw new IllegalArgumentException("duplicate name: " + e.getName());
                    }
                }
            }
    
            public Integer getId() {
                return this.id;
            }
    
            public String getName() { return this.name; }
    
            public static TypeEnum getById(Integer id) {
                return byId.get(id);
            }
    
            public static TypeEnum getByName(String name) {
                return byName.get(name);
            }
        }
    
        public static class TypeClass{
            private Integer id;
            private String name;
    
            public Integer getId() {
                return id;
            }
    
            public void setId(Integer id) {
                this.id = id;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
        }
    }