Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fill in map inside target object by copying values from source object using -MapStruct?

I am new to Mapstruct. I have a scenario where, in my target object I have a java map with key value pair<String,String> and I have to fill this map using source objects inner object properties/data member values.

My code is something like bellow(dummy code):

public class Student {
    public String name;
    public String rollNo;
    public Map<String, String> marks;
}


public class ExamResult{

    public String stud_name;
    public String Stud_rollNo;
    public Marks marks;
}

public class Marks{
    public Integer English;
    public Integer Maths;
    public Integer Science;
}

How would I manually achieve the same thing like bellow:

Student target;
ExamResult source;
target.setName(source.stud_name);
target.setRollNo(source.Stud_RollNo);
target.marks.put("ENGLISH",source.marks.english_marks);
target.marks.put("MATHS",source.marks.math_marks);
target.marks.put("SCIENCE",source.marks.science_marks);

For direct property mapping I have found code, but not sure how I can map the values to be filled in the marks map.

I had given a thought to use java expression to fill in target map values, but didn't found any documentation or such example of expressions using for target object.

I was thinking to use like bellow but not sure it will work:

    @Mapping(source = "stud_name", target = "name")
    @Mapping(source = "Stud_RollNo", target = "rollNo")
    @Mapping(source = "source.marks.english_marks",target = "java( marks.put(\"ENGLISH\",source.marks.english_marks )")
    @Mapping(source = "source.marks.math_marks",target = "java( marks.put(\"MATHS\",source.marks.math_marks )")
    @Mapping(source = "source.marks.science_marks",target = "java( marks.put(\"SCIENCE\",source.marks.science_marks )")
Student doConvert(ExamResult src)

Any help, any suggestion or any workaround is appreciated. Thanks in Advance.

like image 496
Anonymous Avatar asked Jul 17 '20 20:07

Anonymous


1 Answers

Using expressions in target is not allowed for MapStruct, that's why you couldn't make it work.

Mapping into maps from objects is also not supported yet, we have different issues requesting this feature.

What I would suggest is to use the automatic mapping as much as possible when you can and then resort to @AfterMapping when MapStruct can't do that. So in your case something like:

@Mapper
public interface StudentMapper {

    @Mapping(source = "stud_name", target = "name")
    @Mapping(source = "Stud_RollNo", target = "rollNo")
    @Mapping(target = "marks", ignore = true) // mapped in @AfterMapping
    Student doConvert(ExamResult src)

    @AfterMapping
    default void addStudentMarks(ExamResult result, @MappingTarget Student student) {
        student.marks = new HashMap<>();
        student.marks.put("ENGLISH", result.marks.ENGLISH);
        student.marks.put("MATHS", result.marks.MATHS);
        student.marks.put("SCIENCE", result.marks.SCIENCE);
    }

}
like image 70
Filip Avatar answered Oct 19 '22 00:10

Filip