Как отобразить элементы 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.
Бин PersonalCustomer не отображается. Я не вижу этого в ответе. Но он отлично работает при использовании бульдозера. Все, что мне нужно сделать, это определить его в сопоставлении в конфигурации Dozer XML. Я пробовал аналогичную вещь в mapStruct. Я определил personcalCustomerToPersonalCustomermethod в интерфейсе Mapper с необходимыми сопоставлениями и игнорируя необязательные поля. Хотя в mapperImpl есть реализация, но я не вижу, чтобы она использовалась где-либо в классе impl.
Игнорируя поля, которые имеют @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:compile (default-compile) в службе проекта -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.adedderilult $1.call(MultiThreadedBuilder.java:188) в org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call(MultiThreadedBuilder.java:184) в java.util.concurrent.FutureTask.rk.java Future:266) в java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) в java.util.concurrent.FutureTask.run(FutureTask.java:266) в java.util.concurrent.ThreadPoolExorker.un ThreadPoolExecutor.java:1149) в java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) в java.lang.Thread.run(Thread.java:748) C предоставлено: org.apache.maven.plugin.compiler.CompilationFailureException: ошибка компиляции
Вышеуказанное разрешается, когда я использовал игнорируемое значение имени (@XmlElement(name="AMLLineOfBusiness")). Я не мог понять, что именно здесь происходит.
По умолчанию mapStruct также отображает поля суперкласса. В моем случае класс Customer также получает свойства Role. Нет другого выбора, кроме как использовать ignore=true для каждого свойства. Это довольно беспокойно, так как у меня есть 50 нечетных полей и десятки похожих карт в зависимости от требований сервиса. Я бы хотел, чтобы mapStruct имел функцию игнорирования всех полей по умолчанию или стратегию для отображения только указанных полей.
Обратите внимание, что оба типа источника и назначения здесь одинаковы. Мне нужно только сопоставить определенные поля в зависимости от требования. Я застрял здесь. Я высоко ценю вашу помощь.
1 ответ
Кажется, у вас есть 3 разные проблемы.
- Кажется, что вы пытаетесь достичь, чтобы MapStruct обнаружил все возможные реализации для
Customer
(или посмотреть@XmlSeeAlso
) и используйте метод, который вам нужен. Это невозможно автоматически в MapStruct. Смотрите #131 для запроса существующей функции. - Это должно произойти, если вы не определили свойство правильно. MapStruct фактически просматривает только геттеры и сеттеры (не в поле). Так что, если вы получите
getAM
тогда ваш@Mapping(target = "AMLLineOfBusiness", ignore = true)
- Это похоже на этот вопрос. Может быть, вы можете попробовать повторно использовать конфигурации сопоставления
Возможное решение для 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 не может вывести все возможные реализации.