Как сопоставить элементы JAXB, аннотированные @XMLSeeAlso, с помощью mapStruct?

Я пытаюсь сопоставить bean-компонент, который имеет некоторые элементы JAXB, такие как @XmlSeeAlso, @XmlElement, @XmlSchemaType, как свойства для этого класса.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Customer")
@XmlSeeAlso({PersonalCustomer.class, BusinessCustomer.class})
public class Customer extends Role {

 @XmlElement(name = "AMLLineOfBusiness")
private LOB amlLineOfBusiness;
 // 50 odd properties
 //some properties with XmlElement/XmlSchemaType 
 // getters and setters   
}

@Mapper
public interface CustomerMapper {
     PersonalCustomer personcalCustomerToPersonalCustomer(PersonalCustomer pc);
@Mappings({
    /*Several other ignore mappings*/
    @Mapping(target="AMLLineOfBusiness",ignore=true)
    })
     Customer customerToCustomer(Customer customer);
   }

Теперь я сталкиваюсь с проблемами при отображении с помощью mapStruct.

  1. Bean-компонент PersonalCustomer не отображается. Я не вижу этого в ответе. Но при использовании бульдозера работает отлично. Все, что мне нужно сделать, это определить его в сопоставлении в xml конфигурации dozer. Я пробовал подобное в mapStruct. Я определил personcalCustomerToPersonalCustomermethod в интерфейсе mapper с необходимыми сопоставлениями и игнорированием необязательных полей. Хотя реализация есть в mapperImpl, но я не вижу, чтобы она использовалась где-либо в классе impl.

  2. Игнорируя поля с @XmlElement или @XmlSchemaType, я получаю ошибку компиляции при генерации кода impl. Ниже приведена трассировка статистики ошибок. При использовании amlLineOfBusiness возникла ошибка компиляции.

    [70,2] ошибка: неизвестное свойство «amlLineOfBusiness» в типе результата com.role.Customer. Вы имели в виду "lineOfBusiness"? [ОШИБКА] -> [Справка 1] org.apache.maven.lifecycle.LifecycleExecutionException: не удалось выполнить цель org.apache.maven.plugins: maven-compiler-plugin: 3.5.1: компиляция (компиляция по умолчанию) в службе проекта -jar: ошибка компиляции C: \ Perforce \ service-jar \ 2018.08.0 \ service-jar \ src \ main \ java \ com \ mapstruct \ mapper \ CustomerMapper.java: [70,2] ошибка: неизвестное свойство «amlLineOfBusiness» в результате введите com.role.Customer. Вы имели в виду "lineOfBusiness"? на org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212) на org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:153) на org.apache.maven.lifecycle .internal.MojoExecutor.execute (MojoExecutor.java:145) в org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:108) в org.apache.maven.lifecycle.internal.builderMult.mult $ 1.call (MultiThreadedBuilder.java:188) в org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder $ 1.call (MultiThreadedBuilder.java:184) в java.util.concurrent.FutureTask.run (FutureTask.run : 266) в java.util.concurrent.Executors $ RunnableAdapter.call (Executors.java:511) в java.util.concurrent.FutureTask.run (FutureTask.java:266) в java.util.concurrent.ThreadPoolExecutor ( ThreadPoolExecutor.java:1149) в java.util.concurrent.ThreadPoolExecutor $ Wo rker.run (ThreadPoolExecutor.java:624) в java.lang.Thread.run (Thread.java:748) Вызвано: org.apache.maven.plugin.compiler.CompilationFailureException: сбой компиляции

    Вышеупомянутое разрешено, когда я игнорировал значение имени аннотации (@XmlElement (name = "AMLLineOfBusiness")). Я не мог понять, что именно здесь происходит.

  3. По умолчанию mapStruct также отображает поля суперкласса. В моем случае класс Customer также получает свойства Role. Нет другого варианта, кроме использования ignore = true для каждого свойства. Это довольно беспокойно, так как у меня есть 50 нечетных полей и десятки подобных картографов в зависимости от требований к сервису. Я бы хотел, чтобы у mapStruct была функция игнорирования всех полей по умолчанию или стратегия для сопоставления только указанных полей.

Обратите внимание, что здесь используются одинаковые типы источника и назначения. Мне нужно только сопоставить определенные поля в зависимости от требований. Я застрял здесь. Я высоко ценю вашу помощь.


person Naveen    schedule 30.03.2018    source источник
comment
Можете ли вы поделиться @Mapping, где вы используете amlLineOfBusiness?   -  person Filip    schedule 30.03.2018
comment
@ Филипп. Отредактировал вопрос. Он присутствует в классе Customer. Меня не нужно назначать для текущего обслуживания. Поэтому добавлен тег игнорирования для этого   -  person Naveen    schedule 30.03.2018


Ответы (1)


Похоже, у вас 3 разные проблемы.

  1. Похоже, что вы пытаетесь добиться, чтобы MapStruct обнаружил все возможные реализации для Customer (или см. @XmlSeeAlso) и использовал нужный вам метод. Это невозможно автоматически в MapStruct. См. # 131 для существующего запроса функции.
  2. Это должно произойти, если вы неправильно определили свойство. MapStruct на самом деле изучает только методы получения и установки (а не поля). Итак, если вы получаете getAM, то ваш @Mapping(target = "AMLLineOfBusiness", ignore = true)
  3. Это похоже на этот вопрос. Возможно, вы можете попробовать повторно использовать конфигурации сопоставления

Возможным решением для 1 может быть экземпляр на вашей стороне.

@Mapper
public interface CustomerMapper {
    PersonalCustomer personcalCustomerToPersonalCustomer(PersonalCustomer pc);

    default Customer customerToCustomer(Customer customer) {
        if (customer instanceOf PersonalCustomer) {
            return personalCustomerToPersonalCustomer((PersonalCustomer) pc);
        } else if (customer instanceOf BusinessCustomer) {
            return businessCustomerToBusinessCustomer((BusinessCustomer) pc);
        }
    }
}

Причина в том, что MapStruct является процессором аннотаций, поэтому он генерирует код во время компиляции. С другой стороны, Dozer работает с информацией времени выполнения. Dozer может получить класс во время выполнения и выбрать правильный метод. MapStruct не может вывести все возможные реализации.

person Filip    schedule 30.03.2018
comment
Первая - это моя основная проблема. Я полностью застрял там. Фактически он создает реализацию для personcalCustomerToPersonalCustomer (..) в сгенерированном коде impl. Но я не вижу, чтобы эта реализация метода использовалась где-либо в customerToCustomer (). Таким образом, очевидно, что в результирующем компоненте не выполняется сопоставление. - person Naveen; 30.03.2018
comment
См. Мой отредактированный ответ. Теперь я понимаю, что именно вам нужно. В любом случае это не имеет отношения к @XmlSeeAlso - person Filip; 30.03.2018
comment
Здесь PersonalCustomer и BusinessCustomer расширяют класс Custome. У каждого есть отдельные поля. Теперь, когда я описал вышеупомянутое решение, хотя оно отображает поля указанных PersonalCustomer и BusinessCustomer, но не отображает поля класса Customer. - person Naveen; 03.04.2018
comment
Это странно, поскольку MapStruct просматривает всю иерархию для выполнения сопоставления. Можете ли вы привести пример, и если он действительно не работает, создайте проблему - person Filip; 03.04.2018
comment
Небольшой хак решил проблему. Это появляется, когда я использую этот способ вместе с общей конфигурацией. Это может подождать пока. - person Naveen; 04.04.2018