简体   繁体   English

复杂物体的推土机映射

[英]Dozer mapping for complex objects

I have 2 POJOs as shown below:我有 2 个 POJO,如下所示:

package com.main.java.src;

    public class SourceObj {

    protected String name;
    ...
    ...
    10 String objects

    protected Addresses addresses; 

    ...
    ...
    getter and setter for all fields

    }
---------    
package com.java.main.src;

    public class Addresses {
     protected List<Address> address;
    ...
    getters and setters

} }

    package com.main.java.src;

    public class Address {
       protected String city;

       protected List<Contact> contact;

    ...

    getters & setters
    }

-----
package com.main.java.dest;
    public class DestObj {

    protected String name;
    ...
    ...
    10 String objects

    protected Addresses addresses; 

    ...
    ...
    getter and setter for all fields

    }

----------------
package com.main.java.dest;

    public class Addresses {
     protected List<Address> address;
    ...
    getters and setters
    }

package com.main.java.dest;
    public class Address {
       protected String city;

       protected List<Contact> contact;

    ...

    getters & setters
    }

Now i have the dozer-configuration.xml as follows:

    <?xml version="1.0" encoding="UTF-8"?>
    <mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">
        <configuration>
            <stop-on-errors>true</stop-on-errors>
            <trim-strings>true</trim-strings>
            <relationship-type>non-cumulative</relationship-type>       
        </configuration>

        <mapping>
            <class-a>com.main.java.src.SourceObj</class-a>
            <class-b>com.main.java.dest.DestObj</class-b>
            <field>
                <a>addresses.address</a>
                <b>addresses.address</b>
                <a-hint>com.main.java.src.Address</a-hint>
                <b-hint>com.main.java.dest.Address</b-hint>
            <field> 
        </mapping>
    </mappings>

Now the above mapping copies fields like name from SourceObj to DestObj, but not able to map List of Address from src package to List of Address of dest package.现在,上面的映射将名称等字段从 SourceObj 复制到 DestObj,但无法将 map 地址列表从 src package 复制到目标地址列表 ZEFE90A8E604A7C640E88D03A68 Again inside Address object, there is a list of Contact object.再次在地址 object 内,有一个联系人列表 object。

One solution i found is to write a custom converter which will copy primitive field values one by one and then all objects from one list to another destination list.我发现的一个解决方案是编写一个自定义转换器,它将一个一个地复制原始字段值,然后将所有对象从一个列表复制到另一个目标列表。

But I am looking for a solution in dozer-configuration.xml.但我正在寻找 dozer-configuration.xml 中的解决方案。

After the above xml mappings, i am getting below exception:在上述 xml 映射之后,我得到以下异常:

MapId: null
  Type: null
  Source parent class: com.main.java.src.SourceObj
  Source field name: addresses.address
  Source field type: class java.util.ArrayList
  Source field value: [com.main.java.src.Address@1b65d51d]
  Dest parent class: com.main.java.dest.DestObj
  Dest field name: addresses.address
  Dest field type: java.util.List

java.lang.NullPointerException: null
    at org.dozer.util.ReflectionUtils.invoke(ReflectionUtils.java:329) ~[dozer-5.5.1.jar:?]
    at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.writeDeepDestinationValue(GetterSetterPropertyDescriptor.java:268) ~[dozer-5.5.1.jar:?]
    at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.setPropertyValue(GetterSetterPropertyDescriptor.java:96) ~[dozer-5.5.1.jar:?]
    at org.dozer.fieldmap.FieldMap.writeDestValue(FieldMap.java:96) ~[dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.writeDestinationValue(MappingProcessor.java:939) ~[dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:368) ~[dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.mapField(MappingProcessor.java:307) [dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.map(MappingProcessor.java:267) [dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.mapToDestObject(MappingProcessor.java:216) [dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:196) [dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.mapGeneral(MappingProcessor.java:170) [dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.map(MappingProcessor.java:104) [dozer-5.5.1.jar:?]
    at org.dozer.MappingProcessor.map(MappingProcessor.java:99) [dozer-5.5.1.jar:?]
    at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:120) [dozer-5.5.1.jar:?]

Please advise with the solution for this case.请告知这种情况的解决方案。

Dozer will map anything with the same name and type automatically.推土机将自动 map 任何具有相同名称和类型的东西。 When the fields you want to map have different names, you must explicitly tell Dozer in the mapping which fields to map to each other.当你想要 map 的字段有不同的名称时,你必须在映射中明确告诉 Dozer 哪些字段到 map 相互。 In the question above, the AddressSrc and AddressDest are fields with different names.在上面的问题中,AddressSrc 和 AddressDest 是具有不同名称的字段。 Therefore, you must explicitly tell Dozer to map those two fields to each other.因此,您必须明确告诉 Dozer 到 map 这两个字段。

<mapping>
    <class-a>SourceObj</class-a>
    <class-b>DestObj</class-b>    
    <field>
        <a>addressesSrc</a>
        <b set-method="customSetMethodName">addressesDest</b>
    </field>  
</mapping>

You may need additional mapping instructions to get the result you ultimately want.您可能需要额外的映射指令来获得您最终想要的结果。 However, this is the missing mapping piece you need to get Dozer to map these two fields since they have different names.但是,这是将 Dozer 获取到 map 这两个字段所需的缺失映射部分,因为它们具有不同的名称。

I have found the answer after much trial and error.经过多次反复试验,我找到了答案。 Please refer the below solution.请参考以下解决方案。

<mapping>
  <class-a>com.java.main.src.SourceObj</class-a>
  <class-b>com.java.main.dest.DestObj</class-b>
  <field>><!-- java.util.List to java.util.List -->
     <a is-accessible="true">addresses.address</a>
     <b is-accessible="true">addresses.address</b>
     <a-hint>com.java.main.src.Address</a-hint>
     <b-hint>com.java.main.dest.Address</b-hint>
  </field>
</mapping>

<mapping>
  <class-a>com.java.main.src.Address</class-a>
  <class-b>com.java.main.dest.Address</class-b>
  <field>
     <a get-method="isIsPrimaryAddress">isIsPrimaryAddress</a>
     <b get-method="isIsPrimaryAddress">isIsPrimaryAddress</b>     
  </field>
</mapping>

If for Address object, the getter method is not defined as getFieldName, in that case you need to map as we have mapped isIsPrimaryAddress as shown above.如果对于地址 object,getter 方法未定义为 getFieldName,在这种情况下,您需要 map,因为我们已经映射了 isIsPrimaryAddress,如上所示。 All the other fields names have same names in both Address objects, and so the values will be copied automatically.所有其他字段名称在两个地址对象中具有相同的名称,因此将自动复制值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM