如何使用mapStruct映射使用@XMLSeeAlso注释的JAXB元素?

我正在尝试将具有一些JAXB元素的bean映射为@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。 我没有在回复中看到它。 但是在使用推土机时效果很好。 我需要做的就是在dozer config xml中定义它的映射。 我在mapStruct中尝试过类似的东西。 我在mapper接口中定义了personcalCustomerToPersonalCustomer方法,并使用了必需的映射并忽略了不需要的字段。 虽然mapperImpl中有实现,但我没有看到它在impl类的任何地方使用。

  2. 忽略具有@XmlElement或@XmlSchemaType的字段,我在生成impl代码时遇到编译错误。 以下是错误statck跟踪。 当我使用amlLineOfBusiness时出现编译错误。

    [70,2]错误:结果类型com.role.Customer中的未知属性“amlLineOfBusiness”。 你的意思是“lineOfBusiness”吗? [错误] – > [帮助1] org.apache.maven.lifecycle.LifecycleExecutionException:无法执行目标org.apache.maven.plugins:maven-compiler-plugin:3.5.1:在项目服务上编译(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.life循环的org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153) .internal.MojoExecutor.execute(MojoExecutor.java:145)org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:108)org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder $ 1.call(MultiThreadedBuilder.java:188)atg.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder $ 1.call(MultiThreadedBuilder.java:184)at java.util.concurrent.FutureTask.run(FutureTask.java) :266)java.util.concurrent.Executors $ runnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ThreadPoolExecutor.runWorker( ThreadPoolExecutor.java:1149)java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)C aused by:org.apache.maven.plugin.compiler.CompilationFailureException:编译失败

    当我使用(@XmlElement(name =“AMLLineOfBusiness”))注释的名称值忽略时,解决了上述问题。 我无法理解这里到底发生了什么。

  3. 默认情况下,mapStruct也是映射超类的字段。 在我的例子中,Customer类也获得了Role的属性。 除了在每个属性上使用ignore = true之外,没有其他选项。 这有点忙乱,因为我有50个奇数字段和数十个基于服务要求的类似映射器。 我希望mapStruct具有默认忽略所有字段的function或仅映射指定字段的策略。

请注意,源和目标类型在此处相同。 我只需根据要求映射某些字段。 我被困在这里。 我非常感谢你的帮助。

看起来你有3个不同的问题。

  1. 您正在尝试实现的目的是让MapStruct检测Customer所有可能实现(或参见@XmlSeeAlso )并使用您需要的方法。 在MapStruct中无法自动执行此操作。 有关现有function请求,请参阅#131 。
  2. 如果未正确定义属性,则会发生这种情况。 MapStruct实际上只查看getter和setter(不在字段中)。 所以,如果你得到的是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无法推断出所有可能的实现。