java Mapstruct -为Map属性找到不明确的Map方法

wkftcu5l  于 2023-06-04  发布在  Java
关注(0)|答案(4)|浏览(263)

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

@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;
}

错误是
将属性“ProgramprogramInstance”Map到java.lang.String时发现了不明确的Map方法:java.lang.String mapTitle()、java.lang.String mapSeriesName()。

lf3rwulv

lf3rwulv1#

我检查了你的例子。问题是您尝试定位的字段是String类型的。
所以:

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.用户提供的Map方法
1.直接(源-目标类型相同)
1.Map方法(内置)
1.类型转换
如果这一切都失败了,MapStruct会尝试执行两个步骤的方法:
1.Map法
1.Map方法-类型转换
1.类型转换-Map法
在6处,它找到2个限定方法(ProgramString)。这可能是MapStruct中的一个错误,它选择了不符合@Named的方法(需要检查这是否是故意的)。否则,我会写一个问题。
最简单的解决方案是:调整目标:

public class IvpVodOfferStatusDTO {

    private Integer seasonNumber;
    private Integer episodeNumber;
}

你的意图可能是什么(我猜)..否则,您可以更改签名,不返回Integer,而是返回String

eaf3rand

eaf3rand2#

即使数据类型匹配,如果在qualifiedByName处给出的名称没有在中定义为bean示例,也可能发生这种情况
因为如果没有匹配的@Named限定符,注入器将不知道将哪个bean绑定到哪个变量

@Mapping( source = "firstName", target = "passenger.firstName", qualifiedByName = "mapFirstName" )
public abstract Passenger mapPassenger( Traveller traveller );

@Named( "mapFirstName" )
String mapFirstName( String firstName)
{
}
wlwcrazw

wlwcrazw3#

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

c9qzyr3d

c9qzyr3d4#

还请注意,如果你有循环依赖,你可能会得到这个:

ObjectA -> ObjectB -> ObjectA -> ObjectB

大多数情况下,它将被报告为不明确的条目。解决方案是不在ObjectB中引用Object A。

相关问题