我本来打算在github上创建一个问题,但是问题模板说我宁愿先在这里讨论它,所以我们开始:
我正在尝试使用Mapstruct来生成从一个WSDL生成的实体集到另一个实体集的映射。但是,如果不添加“默认”方法(手动映射),则无法工作!这似乎很奇怪,因为我认为这种映射对于Mapstruct来说并不困难。repro案例出现在这里:https://github.com/62mkv/wsdl-mapstruct-repro-case
守则的要点如下:
@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.bind.JAXBElement映射(javax.xml.bind.JAXBElement值)“。fromCloud(org.system.wsdl.cloud.SellGarlicRequest org.system.wsdl.legacy.SellGarlicRequest请求);
基本上,映射如下: EntityNew -> JaxbElement -> FieldNew -> FieldOld -> JaxbElement -> EntityOld
正如我在这里所读到的(https://stackoverflow.com/a/46015381/2583044),从JaxbElement到T的映射对于MapStruct来说是微不足道的,而要从T映射到JaxbElement,就必须使用“use”注释并提供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())
);
}这是mapstruct中的一个潜在问题,还是我只是不知道如何把它煮好?
发布于 2020-03-03 19:38:20
问题是,MapStruct将对象工厂方法(带参数)视为映射方法。因此,它提供了一个目标,但它也有一个源。如果你意识到这一点,那么映射就会突然变得不对称(就像它最初出现的那样)。
简单的解决方案是指导MapStruct如何处理这个问题。
所以:试试这个:
@Mapper(uses = {
org.system.wsdl.legacy.ObjectFactory.class
})
public interface WsMapper {
org.system.wsdl.legacy.GarlicParameterCollection garlicParameterCollectionToGarlicParameterCollection(org.system.wsdl.cloud.GarlicParameterCollection collection);
@Mapping( target = "inputParameters", source = "inputParameters.value") // this instructs MapStruct to use value of the source JAXBElement (for which it has an object factory method) instead of trying to map JAXBElement to JAXBElement.
org.system.wsdl.legacy.SellGarlicRequest fromCloud(org.system.wsdl.cloud.SellGarlicRequest request);
}最后但并非最不重要的是,您需要定义第一个方法garlicParameterCollectionToGarlicParameterCollection,它最初让我感到惊讶。
原因: MapStruct要么尝试: 1.查找一个映射方法(如果不使用这个方法,它就不存在),或者2.尝试生成一个直接映射(检查它是否能够为源和目标上的所有属性找到方法)。
但是,MapStruct无法找到这种映射的直接情况(原则上,它需要在其路径上应用所有其他可能的映射(例如,对象工厂中的所有方法),然后尝试生成一个映射方法,如2中所解释的,这可能是很多组合。这个功能是不存在的(而且我猜它也是负载密集型的)。
https://stackoverflow.com/questions/60493233
复制相似问题