MapStruct:如何将输入对象传递给表达式?

MapStruct: How to pass input object to expression?

在 MapStruct 1.1 版中。0.Final,这是可能的....

@Mappings({
    @Mapping(target = "transaction.process.details", expression = "java(MappingHelper.mapDetails(request))"),
     //more mappings
})
Response requestToResponse(Request request);

这是可能的,因为 mapDetails 方法(巧合?)生成到 requestToResponse 方法中。这就是 request 不为空的原因。

现在,由于 1.1.0.Final 不能与 Lombok 一起使用,我不得不升级到 1.2.0.CR2。使用此版本,mapDetails 将生成到一个单独的方法中,其中 request 未传递,因此 request 现在在此方法中为空,我得到一个带有表达式的 NPE。 (现在是requestToResponse的子方法。)

我是不是用错了这个表达式,所以它只是巧合,还是新版本有错误?如果没有错误,我该如何正确地将 request 实例传递给表达式?

你曾经/正在滥用这个表达。您需要做的是将目标映射到源参数。

@Mapper(uses = { MappingHelper.class })
public interface MyMapper {

    @Mappings({
        @Mapping(target = "transaction.process.details", source = "request"),
         //more mappings
    })
    Response requestToResponse(Request request);
}

MapStruct 然后应该创建中间方法并使用 MappingHelper 并调用 mapDetails 方法。如果您有多种方法从 Request 映射到任何类型 details,那么您将需要使用合格的映射(请参阅文档中的更多内容 here)。

它看起来像:

public class MappingHelper {
    @Named("mapDetails") // or the better type safe one with the meta annotation @Qualifier
    public static String mapDetails(Request request);
}

您的映射将如下所示:

@Mapper(uses = { MappingHelper.class })
public interface MyMapper {

    @Mappings({
        @Mapping(target = "transaction.process.details", source = "request", qualifiedByName = "mapDetails"), //or better with the meta annotation @Qualifier qualifiedBy
         //more mappings
    })
    Response requestToResponse(Request request);
}