如何从JaxbElement映射<;X>;到JaxbElement<;Y>;使用MapStruct

如何从JaxbElement映射<;X>;到JaxbElement<;Y>;使用MapStruct,jaxb,wsdl,mapstruct,Jaxb,Wsdl,Mapstruct,我本来打算在github上创建一个问题,但问题模板说我宁愿先在这里讨论,所以我们开始: 我试图使用Mapstruct生成从一个WSDL生成的实体集到另一个实体集的映射。但是,如果不添加“默认”方法(手动映射),它将无法工作!这似乎很奇怪,因为我认为这种映射对于Mapstruct来说应该不难。repo案例如下: @Mapper(uses = { org.system.wsdl.legacy.ObjectFactory.class }) public interface WsMapper {

我本来打算在github上创建一个问题,但问题模板说我宁愿先在这里讨论,所以我们开始:

我试图使用Mapstruct生成从一个WSDL生成的实体集到另一个实体集的映射。但是,如果不添加“默认”方法(手动映射),它将无法工作!这似乎很奇怪,因为我认为这种映射对于Mapstruct来说应该不难。repo案例如下:

@Mapper(uses = {
    org.system.wsdl.legacy.ObjectFactory.class
})
public interface WsMapper {

org.system.wsdl.legacy.SellGarlicRequest fromCloud(org.system.wsdl.cloud.SellGarlicRequest request);

}
守则的要点如下:

@Mapper(uses = {
    org.system.wsdl.legacy.ObjectFactory.class
})
public interface WsMapper {

org.system.wsdl.legacy.SellGarlicRequest fromCloud(org.system.wsdl.cloud.SellGarlicRequest request);

}
上述代码将无法编译,并显示以下消息:

无法将属性“javax.xml.bind.JAXBElement inputParameters”映射到“javax.xml.bind.JAXBElement inputParameters”。考虑声明/实现映射方法:“javax .xML.bd.jxBelestMmap(javax .xML.bd.jAxBelMess值)”。org.system.wsdl.legacy.SellGarlicRequest fromCloud(org.system.wsdl.cloud.SellGarlicRequest)

基本上,映射将如下所示:EntityNew->JaxbElement->FieldNew->FieldOld->JaxbElement->EntityOld

正如我在这里所读到的(),对于MapStruct来说,从JaxbElement到T的映射是微不足道的,要从T映射到JaxbElement,必须使用“uses”注释并提供ObjectFactory.class,我就是这么做的;然而。。。这似乎还不够

如果我添加这两个方法,代码会编译得很好:

org.system.wsdl.legacy.GarlicParameterCollection garlicParameterCollectionToGarlicParameterCollection(org.system.wsdl.cloud.GarlicParameterCollection collection);

default JAXBElement<org.system.wsdl.legacy.GarlicParameterCollection> garlicParameterCollectionToGarlicParameterCollection(JAXBElement<org.system.wsdl.cloud.GarlicParameterCollection> parameterCollectionJAXBElement) {
    return new org.system.wsdl.legacy.ObjectFactory().createSellGarlicRequestInputParameters(
            this.garlicParameterCollectionToGarlicParameterCollection(parameterCollectionJAXBElement.getValue())
    );
}
org.system.wsdl.legacy.GarlicParameterCollection garlicParameterCollectionToGarlicParameterCollection(org.system.wsdl.cloud.GarlicParameterCollection);
默认JAXBElement garlicParameterCollectionToGarlicParameterCollection(JAXBElement parameterCollectionJAXBElement){
返回新的org.system.wsdl.legacy.ObjectFactory().createSellGarlicRequestInputParameters(
this.garlicParameterCollectionToGarlicParameterCollection(parameterCollectionJAXBElement.getValue())
);
}

这是
mapstruct
中的一个潜在问题,还是我不知道如何烹调好它

问题在于MapStruct将对象工厂方法(带参数)视为映射方法。因此,它提供了一个目标,但它也有一个来源。如果您意识到这一点,那么贴图突然变得不对称(正如最初显示的那样)

简单的解决方案是指导MapStruct如何处理此问题

所以:试试这个:


@映射器(使用={
org.system.wsdl.legacy.ObjectFactory.class
})
公共接口WsMapper{
org.system.wsdl.legacy.GarlicParameterCollection garlicParameterCollectionToGarlicParameterCollection(org.system.wsdl.cloud.GarlicParameterCollection集合);
@Mapping(target=“inputParameters”,source=“inputParameters.value”)//这指示MapStruct使用源JAXBElement的值(它有一个对象工厂方法),而不是尝试将JAXBElement映射到JAXBElement。
org.system.wsdl.legacy.SellGarlicRequest fromCloud(org.system.wsdl.cloud.SellGarlicRequest);
}
最后但并非最不重要的一点是,您需要定义第一个方法
garlicParameterCollectionToGarlicParameterCollection
,这一点最初让我感到惊讶

原因:MapStruct试图: 1.找到一个映射方法(如果不使用此方法,则不存在该方法) 或 2.尝试生成直接映射(通过检查是否可以找到源和目标上所有属性的方法)


但是,MapStruct找不到此映射的直接实例(原则上它需要在其路径上应用所有其他可能的映射(例如,对象工厂中的所有方法),然后尝试生成如2所述的映射方法,这可能是许多组合。该功能不存在(我猜也是负载密集型的)。

问题是MapStruct将对象工厂方法(带参数)视为映射方法。因此,它提供了一个目标,但也有一个源。如果您意识到这一点,那么映射突然变得不对称(正如最初显示的那样)

简单的解决方案是指导MapStruct如何处理此问题

所以:试试这个:


@映射器(使用={
org.system.wsdl.legacy.ObjectFactory.class
})
公共接口WsMapper{
org.system.wsdl.legacy.GarlicParameterCollection garlicParameterCollectionToGarlicParameterCollection(org.system.wsdl.cloud.GarlicParameterCollection集合);
@Mapping(target=“inputParameters”,source=“inputParameters.value”)//这指示MapStruct使用源JAXBElement的值(它有一个对象工厂方法),而不是尝试将JAXBElement映射到JAXBElement。
org.system.wsdl.legacy.SellGarlicRequest fromCloud(org.system.wsdl.cloud.SellGarlicRequest);
}
最后但并非最不重要的一点是,您需要定义第一个方法
garlicParameterCollectionToGarlicParameterCollection
,这一点最初让我感到惊讶

原因:MapStruct试图: 1.找到一个映射方法(如果不使用此方法,则该方法不存在) 或 2.尝试生成直接映射(通过检查是否可以找到源和目标上所有属性的方法)


但是,MapStruct找不到此映射的直接实例(原则上它需要在其路径上应用所有其他可能的映射(例如,对象工厂中的所有方法),然后尝试生成如2所述的映射方法,这可能是许多组合。该功能不存在(我想这也会是负载密集型的)。

可以确认-作为一种魅力!非常感谢,@Sjaak!可以确认-作为一种魅力!非常感谢,@Sjaak!