Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapstruct: custom mapping method for nested objects

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?

like image 909
KGBR Avatar asked Aug 04 '26 09:08

KGBR


1 Answers

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

like image 143
Filip Avatar answered Aug 05 '26 21:08

Filip



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!