Dozer Mapping

Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another. Typically, these Java Beans will be of different complex types.

This mapper helps us to avoid unnecessary mapping code in our application. Internally it uses reflection.

In this post, We are going to see how we can use this with an example.

Assume that we have a “Person” Bean class which contains the first name, last name, age and address fields. We want to map it into another bean class PersonVO. In addition to that, we want to map the name details into NameVO and address details into AddressVo. Let’s look at below to know how we can do that with Dozer.

Here is our Person Bean class.

Person.java


package com.dozerExample;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class Person {

    private String id;

    private String firstName;

    private String lastName;

    private int age;

    private String streetAddress;

    private String city;

    private String state;

    private String zip;

    private String phoneNumber;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

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

    public String getStreetAddress() {
        return streetAddress;
    }

    public void setStreetAddress(String streetAddress) {
        this.streetAddress = streetAddress;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }
}

We want to map the Person Bean into PersonVO bean and also the first name and last name fields are mapped to NameVO and address are mapped to AddressVO.

Here is the PersonVO Bean class contains the person id, age and NameVo and AddressVo fields.

PersonVO


package com.dozerExample;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class PersonVO {

    private String id;

    private int age;

    private NameVO nameVO;

    private AddressVO addressVO;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

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

    public NameVO getNameVO() {
        return nameVO;
    }

    public void setNameVO(NameVO nameVO) {
        this.nameVO = nameVO;
    }

    public AddressVO getAddressVO() {
        return addressVO;
    }

    public void setAddressVO(AddressVO addressVO) {
        this.addressVO = addressVO;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }
}


Here is the NameVO Bean contains the first and last name fields.
NameVO


package com.dozerExample;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class NameVO {

    private String firstName;

    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }

}

Here is the AddressVO Bean contains the stress address, city, state, zip and phone number fields.
AddressVO


package com.dozerExample;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class AddressVO {

    private String streetAddress;

    private String city;

    private String state;

    private String zip;

    private String phoneNumber;

    public String getStreetAddress() {
        return streetAddress;
    }

    public void setStreetAddress(String streetAddress) {
        this.streetAddress = streetAddress;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }
}

We have to include the below dependency in your pom.xml file.
pom.xml


<dependency>
            <groupId>com.github.dozermapper</groupId>
            <artifactId>dozer-core</artifactId>
            <version>6.1.0</version>
 </dependency>

Then, we need to define the bean mapping field details in an XML. Here is the dozer mapping XML.


<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping http://dozermapper.github.io/schema/bean-mapping.xsd">
    <mapping wildcard="true" map-null="false">
        <class-a>com.dozerExample.Person</class-a>
        <class-b>com.dozerExample.PersonVO</class-b>
        <field>
            <a>firstName</a>
            <b>nameVo.firstName</b>
        </field>
        <field>
            <a>lastName</a>
            <b>nameVo.lastName</b>
        </field>
        <field>
            <a>streetAddress</a>
            <b>addressVo.streetAddress</b>
        </field>
        <field>
            <a>city</a>
            <b>addressVo.city</b>
        </field>
        <field>
            <a>state</a>
            <b>addressVo.state</b>
        </field>
        <field>
            <a>zip</a>
            <b>addressVo.zip</b>
        </field>
        <field>
            <a>phoneNumber</a>
            <b>addressVo.phoneNumber</b>
        </field>
    </mapping>
</mappings>

Now, Let’s use the above mapping file and convert Person into PersonVO and vice versa.



package com.dozerExample;

import org.dozer.DozerBeanMapperBuilder;
import org.dozer.Mapper;

import java.util.UUID;

public class DozerApp {

    public static final String PERSON_DOZER_MAPPING_XML = "dozer-mapping.xml";

    private static Mapper mapper = DozerBeanMapperBuilder.create().withMappingFiles(PERSON_DOZER_MAPPING_XML).build();;

    public static void main(String[] args) {
        Person person = new Person();
        person.setId(UUID.randomUUID().toString());
        person.setFirstName("Michael");
        person.setLastName("Keller");
        person.setAge(45);
        person.setStreetAddress("102 walker st");
        person.setCity("Delaware");
        person.setState("OH");
        person.setZip("45454");
        person.setPhoneNumber("614-434-4535");
        PersonVO personVO = mapper.map(person, PersonVO.class);
        System.out.println("Converting from person to personVO" + personVO);
        Person newPerson = mapper.map(personVO, Person.class);
        System.out.println("Converting from personVO to person" + newPerson);
    }
}

The following is the output of the above program.


Converting from person to personVOcom.dozerExample.PersonVO@467aecef[id=bd993f0e-48f6-4bf7-a942-f902c156ffd4,age=45,nameVO=com.dozerExample.NameVO@5bfbf16f[firstName=Michael,lastName=Keller],addressVO=com.dozerExample.AddressVO@25af5db5[streetAddress=102 walker st,city=Delaware,state=OH,zip=45454,phoneNumber=614-434-4535]]
Converting from personVO to personcom.dozerExample.Person@5f3a4b84[id=bd993f0e-48f6-4bf7-a942-f902c156ffd4,firstName=Michael,lastName=Keller,age=45,streetAddress=102 walker st,city=Delaware,state=OH,zip=45454,phoneNumber=614-434-4535]

Advertisements