Nested Iterable to Non-Iterable mapping?

1,423 views
Skip to first unread message

Andrea Lincetto

unread,
Dec 5, 2016, 5:08:12 PM12/5/16
to mapstruct-users
Hi,
I've posted on StackOverflow (link to SO question) an help request about MapStruct and the possibility to map a nested Iterable to a Non Iterable property.
For example, I would like to write something like this :

@Mapping(target = "emailaddress", source = "emails[0].emailAddress"}

I know I can write a Qualifier to extract (e.g. the first) an element from an iterable to map its value to a plain field, but how to use the dot notation to extract a field of the extracted element?
Any suggestion will be appreciated.
Thank you
Andrea

Filip Hrisafov

unread,
Dec 5, 2016, 5:21:46 PM12/5/16
to mapstruct-users
Hey Andrea,

I posted a comment on SO. I am not sure if you can achieve what you are looking for without using an expression. Maybe the others have a better idea.

Cheers,
Filip

Andrea Lincetto

unread,
Dec 5, 2016, 5:31:48 PM12/5/16
to mapstruct-users
Hi Filip,
thank you for your help, but with the solution you propose I have to implement a method for each specific type/field contained in the Iterable. 
I would like to access to nested field of this type with a dot notation (e.g. emails[0].emailAddress or phoneNumbers[0].prefix) without writing a method for each pair of type+field.
Andrea

Sjaak Derksen

unread,
Dec 5, 2016, 5:41:16 PM12/5/16
to mapstruct-users
Hi Andrea,

The dotted method (or EL) is not fully implemented. There's still somewhere an issue on our list to do something like that.

However, I don't understand you have to implement a method for each specified type/field. You can do this with generics. See our example here: https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-iterable-to-non-iterable/src/main/java/com/mycompany/mapper/util

I the standard behavior is to always take the first element, you can leave the qualifier out and just refer to the handwritten mapper. You can also write an abstract class as mapper and make one implemented method doing the same.

Cheers,
Sjaak

Filip Hrisafov

unread,
Dec 5, 2016, 5:44:51 PM12/5/16
to mapstruct-users
Hey Sjaak,

Andrea wants to call a method on the generic to get the mapping. 

There is one other way that you can do it. You could use the expression attribute of the @Maping. For example 
@Mapping(target = "emailaddress", expression = "emails != null && !emails.isEmpty() ? emails.get(0).getEmailAddress() : null"}. You can use emails if they are part of the mapping method, if emails is an attribute of the source parameter then you will have to do source.getEmails() 

@Sjaak, do you think that something like the expression is possible with the generic method?

Sjaak Derksen

unread,
Dec 5, 2016, 5:55:34 PM12/5/16
to mapstruct-users

Ok. I see your point.. Don't have an answer either. The index breaks the dotted notation. The only solution I see in the longer run is: https://github.com/mapstruct/mapstruct/issues/244.

Best regards,
Sjaak
Message has been deleted

Andrea Lincetto

unread,
Dec 5, 2016, 6:04:07 PM12/5/16
to mapstruct-users
Ok, I'll check that issue.
Thank you very much @Sjaak and @Filip
Andrea
Reply all
Reply to author
Forward
0 new messages