【问题标题】:Mapstruct - Ambiguous mapping methods found for mapping propertyMapstruct - 为映射属性找到不明确的映射方法
【发布时间】:2019-07-04 12:59:00
【问题描述】:

我正在使用 mapstruct 从一个 DTO 映射到另一个。我有多个默认方法,但其中 2 个返回值为 String 并且使用与输入参数相同的类给我“使用 java Mapstruct 的模糊映射方法”错误。我在这里添加代码的相关部分:

@Mappings({
     @Mapping(source = "programInstance", target = "title", qualifiedByName = "title"),
     @Mapping(source = "programInstance", target = "seriesName", qualifiedByName = "seriesName"),
     @Mapping(source = "programInstance", target = "season", qualifiedByName = "season"),
     @Mapping(source = "programInstance", target = "epNumber", qualifiedByName = "epNumber"),
 })
 DTO1 mapDTOs (DTO2 dto2);

  @Named("title")
default String mapTitle(Program programInstance) {
    Optional<String> title = Utils.getObject(() -> programInstance.getTitle().getDescriptions().get(0).getValue());
    if (title.isPresent())
        return title.get();
    return null;
}
@Named("seriesName")
default String mapSeriesName(Program programInstance) {
    Optional<String> seriesName = Utils.getObject(() -> programInstance.get(0).getProgram().getTitle().getDescriptions().get(0).getValue());
    if (seriesName.isPresent())
        return seriesName.get();
    return null;
}
 @Named("season")
default Integer mapSeasonNumber(Program programInstance) {
    Optional<Integer> season = Utils.getObject(() -> programInstance.get(0).getSeasonOf().get(0).getOrderNo());
    if (season.isPresent())
        return season.get();
    return null;
}

@Named("epNumber")
default Integer mapEpNumber(Program programInstance) {
    Optional<Integer> epNumber = Utils.getObject(() -> programInstance.getEpOf().get(0).getOrderNo());
    if (epNumber.isPresent())
        return epNumber.get();
    return null;
}

错误是

映射属性“程序”的映射方法不明确 programInstance" 到 java.lang.String: java.lang.String mapTitle(), java.lang.String mapSeriesName().

【问题讨论】:

  • 您确定您使用的是org.mapstruct.Named 而不是其他的吗?
  • @Filip 是的,我正在使用 org.mapstruct.Named
  • 刚刚在我们的 1.3 代码库上验证了您的示例。它有效
  • 但是.. 我还发现方法的名称有偏差.. mapSeriesName.. 你的例子有一个签名mapSeriesName1 .. 你有没有机会指向一个用过的映射器?是否有更多方法携带相同的@Named
  • sjaak:那是一种类型,抱歉,编辑了代码。我的版本是 1.2,现在尝试更改为 1.3 - 错误仍然存​​在.. 是的,我有更多带有相同源程序的 @Named 方法..

标签: java mapstruct


【解决方案1】:

我检查了您的示例。问题是您尝试定位的字段是字符串类型。

所以:

public class IvpVodOfferStatusDTO {

    private String seasonNumber;
    private String episodeNumber;
} 

MapStruct 尝试将其与您提供的签名匹配:

 @Named("season")
default Integer mapSeasonNumber(Program programInstance) {
    Optional<Integer> season = Utils.getObject(() -> programInstance.get(0).getSeasonOf().get(0).getOrderNo());
    if (season.isPresent())
        return season.get();
    return null;
}

@Named("epNumber")
default Integer mapEpNumber(Program programInstance) {
    Optional<Integer> epNumber = Utils.getObject(() -> programInstance.getEpOf().get(0).getOrderNo());
    if (epNumber.isPresent())
        return epNumber.get();
    return null;
}

MapStruct 有一个预定义的尝试顺序:

  1. 用户提供的映射方法
  2. 直接(源-目标类型相同)
  3. 映射方法(内置)
  4. 类型转换

如果这一切都失败了,MapStruct 会尝试执行一些 2 步方法:

  1. 映射方法-映射方法
  2. 映射方法-类型转换
  3. 类型转换-映射方法

在 6. 它找到 2 个限定方法(ProgramString)。这可能是 MapStruct 中的一个错误,它选择了 @Named 不符合条件的方法(需要检查这是否是故意的)。否则,我会写一个问题。

最简单的解决办法是:调整目标:

public class IvpVodOfferStatusDTO {

    private Integer seasonNumber;
    private Integer episodeNumber;
}

您可能想要什么(我猜)。否则您可以更改签名不返回Integer,而是返回String

【讨论】:

    【解决方案2】:

    我遇到了同样的问题并观察到,我的映射器类使用 @Mapper(uses = {BaseMapper.class}) 并使用扩展 BaseMapper 继承了相同的方法。 删除扩展为我解决了这个问题。 因此,您可以通过多种方式查找自定义映射器接收到的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      • 2018-07-09
      • 2016-04-12
      • 1970-01-01
      相关资源
      最近更新 更多