3

I would like to use mapstruct to map between these objects:

MyObj1
-List<MyObj2> myObj2List
--List<MyObj3> myObj3List
---string field1

MyObj4
-List<MyObj5> myObj5List
--List<MyObj6> myObj6List
---int field1

Question: can i somehow tell mapstruct to map the field1 from string to int OTHERWISE than the default Integer.parseInt(...)?

Changing the types of the inner objects is not an option. I know there is an annotaion

 @Mapping(source = "myObj2List.myObj3List.field1", target = "myObj5List.myObj6List.field1", qualifiedByName = "methodToMapWith")
 public MyObj4 field1Mapper(MyObj1input);
    
 @Named("methodToMapWith") 
 public static int methodToMapWith(string input) { 
    return ...[custom logic]...; 
 }

but since these are nested objects, this way i get an error saying No property named "myObj2List.myObj3List.field1" exists in source parameter(s). I must be formulating the source wrong. Any help please?

4
  • Shouldn't that be (source = "myInnerObj1.field1", target ="myInnerObj2.field1", qualifiedByName....)? Commented Nov 2, 2020 at 15:49
  • I updated the object structure to better reflect the real version. Commented Nov 2, 2020 at 16:09
  • Still it is not a real version of your problem unless you are naming all wrong. What are these fieldNameInSource, fieldnameInTarget names mean and why they do not correspond to any field name in your classes declarations? Commented Nov 2, 2020 at 16:19
  • I have further edited, made it more clear. Thank you for the help! Commented Nov 2, 2020 at 16:36

1 Answer 1

2

You are trying to define mapping on collections. This is not supported by MapStruct.

When using

@Mapping(source = "myObj2List.myObj3List.field1", target = "myObj5List.myObj6List.field1", qualifiedByName = "methodToMapWith")

You are actually telling MapStruct that you want the property myObj3List from the myObj2List to be used. However, myObject2List is not a bean, but a collection.

You actually mean to tell MapStruct to pass the mapping to the created iterable mapping for the single elements.

I think that there is a feature request to support something like that.

In order to support what you need you'll need to add mapping methods between the different object.

e.g.

 @Mapping(source = "myObj2List", target = "myObj5List")
 public MyObj4 field1Mapper(MyObj1 input);

 @Mapping(source = "myObj3List", target = "myObj6List")
 public MyObj5 map(MyObj2 input);

 @Mapping(target = "field1", qualifiedByName = "methodToMapWith")
 public MyObj6 map(MyObj3 input);
    
 @Named("methodToMapWith") 
 public static int methodToMapWith(string input) { 
    return ...[custom logic]...; 
 }

When target and source are identical you don't have to define them, you can just define target and qualifiedByName

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.