【问题标题】:Mapping Hierrachical Beans using mapstruct使用 mapstruct 映射分层 Bean
【发布时间】:2018-09-14 09:10:09
【问题描述】:

这是this问题的扩展。

 class Customer{
  // distinct properties
}
class RetailCustomer extends Customer{
  // distinct properties
}

class WholeSaleCustomer extends Customer{
 // distinct properties
}

class CustomerDO {
 // String custType ; // flag used to determine if Customer is wholeSale or Retail
 //few properties same as Customer/WholeSaleCustomer/RetailCustomer
 // few distinct properties
}

@Mapper
public interface CustomerMapper{

           default Customer toCustomer(CustomerDO customerDO) {
                 String custType = customerDO.getCustType();
                if("W".equalsIgnoreCase(custType)){
                   return toWholeSaleCustomer(customerDO);
                  }
                 else {
                  return toRetailCustomer(CustomerDO);
                   }
           }
        @Mappings({
              @Mapping(source="a", target="b"),
               @Mapping(source="c", target="d"),
               @Mapping(source="m", target="m")
            })
         WholeSaleCustomer toWholeSaleCustomer(CustomerDO customerDO);

       @Mappings({
              @Mapping(source="e", target="f"),
               @Mapping(source="g", target="h"),
               @Mapping(source="n", target="n")
            })
         RetailCustomer toRetailCustomer(CustomerDO customerDO);
}

我需要根据 CustomerDO 中的 custType 标志从 CustomerDO 映射到 WholeSaleCustomer/RetailCustomer。但是上面定义的映射器不起作用。编译时出现以下错误

 CustomerMapper.java:[23,34] Ambiguous mapping methods found for mapping property "com.domain.CustomerDO customerDO" to com.role.Customer: com.role.Customer: toCustomer
r(com.domain.CustomerDO customerDO), com.role.WholeSaleCustomer toWholeSaleCustomer(com.domain.CustomerDO wsCustomer), com.role.RetailCustomer toRetailCustomer(com.domain.CustomerDO wsCustomer)

但是,如果我将 toCustomer(CustomerDo customerDO) 签名更改为 toCustomer(Object customerDO) 并删除 toWholeSaleCustomer/toRetailCustomer 中的任何一个,它就可以工作。它只会映射两种类型中的任何一种。但我两者都想要。我对 Service Bean 有类似的情况。有几个子服务。我应该能够在需要时将它们全部映射

【问题讨论】:

    标签: java mapstruct object-object-mapping


    【解决方案1】:

    你要找的是Mapping method selection based on qualifiers

    因此,如果您的客户对象如下所示:

    class WholeSaleCustomer extends Customer {
     // distinct properties
    }
    
    class CustomerDO {
     // String custType ; // flag used to determine if Customer is wholeSale or Retail
     //few properties same as Customer/WholeSaleCustomer/RetailCustomer
     // few distinct properties
        private CustomerDO customerDO;
    }
    

    然后你必须告诉 MapStruct 它需要使用哪种方法来执行映射。所以你的映射器看起来像:

    @Mapper
    public interface CustomerMapper {
    
            @Named("baseCustomer")
            default Customer toCustomer(CustomerDO customerDO) {
                String custType = customerDO.getCustType();
                if("W".equalsIgnoreCase(custType)){
                    return toWholeSaleCustomer(customerDO);
                }
                else {
                    return toRetailCustomer(CustomerDO);
                }
            }
    
            @Mappings({
                @Mapping(source="customerDO", qualifiedByName = "baseCustomer"),
                @Mapping(source="c", target="d"),
                @Mapping(source="m", target="m")
            })
            WholeSaleCustomer toWholeSaleCustomer(CustomerDO customerDO);
    
            @Mappings({
                @Mapping(source="customerDO", qualifiedByName = "baseCustomer"),
                @Mapping(source="g", target="h"),
                @Mapping(source="n", target="n")
            })
            RetailCustomer toRetailCustomer(CustomerDO customerDO);
    }
    

    @Named 应该来自org.mapstruct.Named

    【讨论】:

    • customerDO 既不是 WholeSaleCustomer 也不是 RetailCustomer 的财产。除了。我不明白你到底做了什么。无论如何它都不起作用。它给了我编译错误,说缺少属性目标。我希望你清楚地理解我的问题。观察:映射器接口中的所有三个方法都具有相同的参数和相同的返回类型。如果我将方法参数更改为三种不同类型,则没有问题。正在生成代码。我不确定这是一个问题还是我做错了什么。
    • 他们没有相同的回报目标。他们都是不同的。他们只是有相同的来源。当然,如果您更改类型,它会起作用。您查看我发布的文档链接了吗?请使用您得到不明确映射错误的确切属性更新您的问题
    • 是的。但是他们有亲子关系。我确实查看了文档。
    • 请为您的类型提供更多信息。哪个属性是您收到错误的地方?
    猜你喜欢
    • 2016-04-06
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2018-12-10
    • 1970-01-01
    相关资源
    最近更新 更多