как отобразить из JaxbElement <X>в JaxbElement <Y>с MapStruct - PullRequest
0 голосов
/ 02 марта 2020

Я собирался создать проблему на github, но в шаблоне проблемы говорится, что я бы сначала обсудил ее здесь, поэтому здесь мы go:

Я пытаюсь использовать Mapstruct для генерации отображений из один сгенерированный WSDL набор сущностей другому. Однако без добавления метода «по умолчанию» (ручное отображение) он не работает! Это кажется странным, так как я ожидаю, что такое отображение не должно быть сложным для Mapstruct. репро случай здесь: 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 map (значение javax. xml .bind.JAXBElement)». org.system.wsdl.legacy.SellGarlicRequest fromCloud (запрос org.system.wsdl.cloud.SellGarlicRequest);

в основном, отображение будет go следующим образом: EntityNew -> JaxbElement -> FieldNew - > FieldOld -> JaxbElement -> EntityOld

, как я читал здесь ({ ссылка }), отображение из JaxbElement в T тривиально для MapStruct и для преобразования из T в JaxbElement один должен использовать аннотацию «использует» и предоставить 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 или я просто не знаю, как его хорошо приготовить?

1 Ответ

2 голосов
/ 03 марта 2020

Проблема в том, что 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, что может быть много комбинаций. Эта функциональность не существует (и я думаю, будет интенсивной нагрузки).

...