Search code examples
javamappingclonejavabeansdozer

How to do mapping for deep (or nested) objects properties using Dozer?


I am having a requirement to map properties of an object which is having nested objects ( deep) to a DTO object. Actually I want to Deflate the complex object to simple DTO with all the properties of even nested objects. I tried BeanUtils but that also don't do deep copy. So I'm exploring Dozer to implement the solution. But even Dozer is mapping first level properties but not deep level nested object properties.

Here are my classes :

    public class Child1  {
    private String name = "MyName";
    private String address = "ABC";

    public TestDTO dto = new TestDTO("50", "USA");

    public TestDTO getDto() {
        return dto;
    }

    public void setDto(TestDTO dto) {
        this.dto = dto;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }   
}


    public class TestDTO {

    public TestDTO(){}

    public TestDTO(String age, String country) {
        super();
        this.age = age;
        this.country = country;
    }

    private String age = "27";

    private String country = "Canada";

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

}

This is the destination I want do deflate all te properties ( even from nested object TestDTO :

    public class TestFacade {

    public String name ;
    public String address;
    private String age ;
    private String country ;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }


}

My mapping file ( I tried wit NO config file also but it was not working so I added a mapping file :

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

   <mapping>
    <class-a>Child1</class-a>
    <class-b>TestFacade</class-b>
</mapping>
<mapping>
    <class-a>TestDTO</class-a>
    <class-b>TestFacade</class-b>
    <field>
        <a is-accessible="true">country</a>
        <b is-accessible="true">country</b>
    </field>
    <field>
        <a>age</a>
        <b is-accessible="true">age</b>
    </field>
</mapping>

Finally my Test File :

  public class QuickTest {


    public static void main(String[] args) {
        Child1 ch = new Child1();
        System.out.println("Get" + ch.getDto().getCountry());


        List myMappingFiles = new ArrayList();
        myMappingFiles.add("dozerMapping.xml");
        DozerBeanMapper mapper = new DozerBeanMapper(myMappingFiles);
        TestFacade f =  mapper.map(ch, TestFacade.class);
        System.out.println(ToStringBuilder.reflectionToString(f));

    }

}

Here is the output:

TestFacade@13adc56[name=MyName,address=ABC,age=<null>,country=<null>]

The age and country properties from nested object are not mapping?


Solution

  • I found the solution myself...

    Contents of my mapping file was wrong. I should use "." notation for nested objects.

    so right contents of mapping file :

    <mapping>
    <class-a>Child1</class-a>
    <class-b>TestFacade</class-b>
    </mapping>
    <mapping>
    <class-a>TestDTO</class-a>
    <class-b>TestFacade</class-b>
    <field>
        <a>dto.country</a>
        <b>country</b>
    </field>
    <field>
        <a>dto.age</a>
        <b >age</b>
    </field>
    

    output :
    
    TestFacade@13adc56[name=MyName,address=ABC,age=50,country=USA]