MapStruct map Protobuf (proto3) to Java POJO
Asked Answered
P

1

1

I'm trying to map from Protobuf to POJO. Here's the POJO:

public class CreateNodesAllDataDto {
    private List<UpsertNodeDto> tables;

    private List<UpsertColumnDto> columns;
}

where upsertNodeDto is the following:

public class UpsertNodeDto {
    @NotNull
    private String workspaceId;

    @NotNull
    private String id;

    @NotNull
    private String name;
}

And here's the Protobuf:

message UpsertNodeAllDataInput {
  repeated UpsertTableInput tables = 1;
  repeated UpsertColumnInput columns = 2;
}

message UpsertTableInput {
  string workspace_id = 1;
  string id = 2;
  string name = 3;
}

You get the idea.

The problem right now is that MapStruct does not map the repeated fields in Protobuf because the getters for these fields in the generated Java file is name xxx-list. For example, the way to get tables from UpsertNodeAllDataInput is input.getTablesList() rather than input.getTables(), and apparently MapStruct does not recognize that.

First of all there's definitely no Protobuf generation issue, because ModelMapper, a similar-purpose package, works in conversion UpsertNodeAllDataInput and CreateNodesAllDataDto. It is also not an issue of MapStruct installation since it works for POJO to POJO mapping for me. The problem is only one described above.

I've been looking around for a while and have only found answers on mapping POJO to Protobuf. Things like this don't seem to work.

Psychobiology answered 10/4, 2021 at 7:52 Comment(0)
M
2

The following is an excerpt from an example of how to map the repeated fields in Protobuf with MapStruct to POJO (and also using Null check):

import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingConstants;
import org.mapstruct.NullValueCheckStrategy;
import org.mapstruct.ValueMapping;
import org.mapstruct.factory.Mappers;

@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
        nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);


    @Mapping(source = "permissions", target = "permissionsList")
    @Mapping(source = "mainDepartments", target = "mainDepartmentsList")
    @Mapping(source = "departments", target = "departmentsList")
    UserDTO map(User user);

    @Mapping(source = "permissionsList", target = "permissions")
    @Mapping(source = "mainDepartmentsList", target = "mainDepartments")
    @Mapping(source = "departmentsList", target = "departments")
    User map(UserDTO userDTO);

    @ValueMapping(source = "UNRECOGNIZED", target = MappingConstants.NULL)
    Permission map(PermissionDTO permissionDTO);

    PermissionDTO map(Permission perm);


    Department map(DepartmentDTO departmentDTO);
    DepartmentDTO map(Department department);
}  

For the whole example, see:
Source
Discussion_related_to_the_issue,_and_the_source_referencing_comment

Mitre answered 14/5, 2022 at 22:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.