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

时间:2018-03-30 08:16:49

标签: java jaxb mapstruct object-object-mapping

我正在尝试将具有一些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中定义了personcalCustomerToPersonalCustomermethod 接口所需的映射并忽略不是必需的字段。虽然 mapperImpl中有实现,但我没有看到它被使用 在impl类的任何地方。

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

    [70,2]错误:结果类型com.role.Customer中的未知属性“amlLineOfBusiness”。你的意思是“lineOfBusiness”吗? [错误] - > [帮助1] org.apache.maven.lifecycle.LifecycleExecutionException:无法执行目标org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile(default-compile)on  project service-jar:编译失败 C:\ Perforce \ service-jar \ 2018.08.0 \ service-jar \ src \ main \ java \ com \ mapstruct \ mapper \ CustomerMapper.java:[70,2]错误:结果类型com中的未知属性“amlLineOfBusiness”。 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.builder.multithreaded.MultiThreadedBuilder $ 1.call(MultiThreadedBuilder.java:188)         在org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder $ 1.call(MultiThreadedBuilder.java:184)         at java.util.concurrent.FutureTask.run(FutureTask.java:266)         at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511)         at java.util.concurrent.FutureTask.run(FutureTask.java:266)         在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)         at java.util.concurrent.ThreadPoolExecutor $ Worker.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具有默认情况下忽略所有字段的功能 仅映射指定字段的策略。

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

1 个答案:

答案 0 :(得分:1)

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

  1. 您尝试实现的目标似乎是MapStruct可以检测Customer的所有可能实现(或参见@XmlSeeAlso)并使用您需要的方法。这在MapStruct中无法自动执行。有关现有功能请求,请参阅#131
  2. 如果未正确定义属性,则会发生这种情况。 MapStruct实际上只查看getter和setter(不在字段中)。因此,如果你得到的是getAM,那么你的@Mapping(target = "AMLLineOfBusiness", ignore = true)
  3. 这与this问题类似。也许你可以尝试Reusing mapping configurations
  4. 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无法推断出所有可能的实现。