java - 复杂物体的推土机映射

标签 java converters dozer

我有 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
    }

现在我的 dozer-configuration.xml 如下:

    <?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>

现在,上面的映射将名称等字段从 SourceObj 复制到 DestObj,但无法将 src 包中的地址列表映射到 dest 包的地址列表。同样,在 Address 对象内部,有一个 Contact 对象列表。

我发现的一个解决方案是编写一个自定义转换器,它将一个一个地复制原始字段值,然后将所有对象从一个列表复制到另一个目标列表。

但我正在 dozer-configuration.xml 中寻找解决方案。

完成上述 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:?]

这个案例的解决方案是什么?

最佳答案

Dozer 将自动映射具有相同名称和类型的任何内容。当要映射的字段具有不同名称时,必须在映射中显式告诉 Dozer 哪些字段要相互映射。 在上面的问题中,AddressSrc 和 AddressDest 是具有不同名称的字段。因此,您必须明确告诉 Dozer 将这两个字段相互映射。

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

您可能需要额外的映射说明才能获得您最终想要的结果。然而,这是您需要让 Dozer 映射这两个字段所缺少的映射部分,因为它们具有不同的名称。

关于java - 复杂物体的推土机映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58340712/

相关文章:

java - Jpa 存储库特殊词,如 "and' 、 "or"不起作用

Java 第一次找到一个特定的字母

linux - ffmpeg 为手机转换 mp4 视频

java - 如何使用Dozer在类之间复制数据而不破坏目标类

java - DozerConverter 提示其中一个类中的 equals 方法

java - 如果给我一堆组合,每个组合都有 k-1 个元素,如何生成大小为 k 个元素的列表?

java - Android - 在 ImageView 上绘制图片

java - 私有(private)构造函数不影响 Dozer

python - 从 std::vector<double> 到 Python 列表的转换失败( boost python)

c# - 将位图像素转换为字节数组失败