Map List<String> with Mapstruct from Java POJO to Protobuf (proto3)
Asked Answered
Q

2

9

I'm trying to map some POJOs from Java to Protobuf (proto3). Some of them contain Lists. While mapping lists with POJOs (for example List) is no problem, I'm getting a UnsupportedOperationException.

Example with List<Product> (this works corrctly):

ProductProtobuf.Builder map(Product product);

@Mapping(target = "productsList", source = "products")
ResponseProtobuf.Builder map(Response response);

Example with List<String> (this doesn't work):

@Mapping(target = "usersList", source = "users")
ResponseProtobuf.Builder map(Response response);

Additionally, I have some Mapper for builder:

public ResponseProtobuf.Builder responseBuilder() {
    return ResponseProtobuf.newBuilder();
}

public ProductProtobuf build(ProductProtobuf.Builder builder) {
    return builder.build();
}
Quits answered 19/7, 2018 at 7:38 Comment(0)
T
13

The problem is that MapStruct will use getProductsList().addAll(). In order to avoid this you should use CollectionMappingStrategy.ADDER_PREFERRED collectionMappingStrategy. Have a look at the UserMapper from the mapstruct-protobuf3 in the mapstruct examples repo.

In a nutshell you need to add:

@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
    nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)

to your mapper.

One information regarding your builder, in case you are using 1.3.0.Beta1 you won't need it as there is out of the box support for that in MapStruct now.

NB: There was a bug in MapStruct that was not working correctly with ProtocolStringList. This bug has been fixed in 1.3.0.Beta1. If you try with this version it should work (in case your productList is a String)

Thetos answered 20/7, 2018 at 20:30 Comment(4)
I forgot to write that I already used: @Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) The problem occures ONLY for List<String> because MapStruct would create an object of type ProtocolStringList (instead of String<List>), which is an interface and therefore can't be used.Quits
Can you update your issue with this information, please. I will update the answer with the fixThetos
How about from Protobuf to Java POJO?Jonajonah
@Jonajonah for that, please see: https://mcmap.net/q/1173932/-mapstruct-map-protobuf-proto3-to-java-pojoChalcopyrite
P
1

I faced with the same issue and solve it like this:

    @AfterMapping
    void afterMapping(@MappingTarget ResponseProtobuf.Builder target, Response response) {
       target.addAllProducts(response.getProducts());
    }
Plot answered 18/9, 2023 at 9:46 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.