• Home
  • RSS Feed
  • Log in


Dozer Mapping
Posted by Amit Jain mid-morning: September 24th, 2007

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 blog will explain you how to convert one Java Bean into another Java Bean by using context type mapping[Dozer mappings], also you can convert one variable type into another variable type by defining them into XML file.

Dozer supports different type of mappings:
1. Simple property mapping
2. Complex type mapping
3. Bi-directional mapping
4. implicit-explicit mapping
5. Recursive mappings
Dozer supports mapping for collection attributes, which is required to element level mapping.
Many a times we need a context based mapping with Dozer so as to control number of fields conversion. Let’s take an example of converting

SourceClass to DestinationClass.

public class SourceClass {
	private String sourceStringForInteger;
	private String sourceStringForLong;
	private String sourceStringForint;
	private String sourceStringForString;
	private List sourceCol;
	…
}

public class DestinationClass {
	private Integer sourceStringForInteger;
	private Long sourceStringForLong;
	private int sourceStringForint;
	private String sourceStringForString;
	private List destCol;
	…
}

You can see SourceClass contains sourceCol variable of type List, which we are converting into destCol variable of type List in DestinationClass.
Here sourceCol is an object type of SourceChildClass and destCol is an object of DestinationChildClass.

public class SourceChildClass {
	private String prop1;
	private String prop2;
	private String prop3;
	…
}

public class DestinationChildClass {
	private Integer prop1;
	private Integer prop2;
	private Integer prop3;
	…
}

Usecase 1 [Simple conversion of source object into destination object.]

We will use map-id attribute to name the cases.
In one service call/conversion we want to convert SourceClass into DestinationClass (say caseA)

<mapping map-id="caseA">
      <class-a>package.SourceClass</class-a>
      <class-b>package.DestinationClass</class-b>
      <field>
       <a>sourceCol</a>
       <b>destCol</b>
       <a-hint>package.SourceChildClass</a-hint>
       <b-hint>package.DestinationChildClass</b-hint>
      </field>
</mapping>

In this mapping

1. Tag <class-a> value source class
2. Tag <class-b> value destination
3. Tag <a> value collection variable in source class
4. Tag <b> value collection variable in destination class
5. Tag <a-hint> Object type of collection defines as tag <a> value.
6. Tag <b-hint> Object type of collection defines as tag <b> value.
7. Other SourceClass fields will implicitly convert into DestinationClass fields irrespective of there data types, like sourceStringForInteger a variable of String type in SourceClass, dozer will convert this variable into Integer type in DestinationClass.

Let’s see we want to exclude sourceStringForInteger variable define SourceClass (say caseB).

<mapping map-id="caseB">
      <class-a>package.SourceClass</class-a>
      <class-b>package.DestinationClass</class-b>
      <field>
       <a>sourceCol</a>
       <b>destCol</b>
       <a-hint>package.SourceChildClass</a-hint>
       <b-hint>package.DestinationChildClass</b-hint>
      </field>

<field-exclude>
         	<a> sourceStringForInteger </a>
         	<b> sourceStringForInteger </b>
          </field-exclude>
   </mapping>

In this mapping
Add tag and define variable names, which you want to exclude.

Let’s see how code look like. sourceClass is an object of type SourceClass which has to be converted into DestinationClass

DestinationClass destinationClass = (DestinationClass) mapper.map (sourceClass, DestinationClass.class,"caseA");

Definition of mapper is done as bean in Spring.

Here we pass a third string argument indicating the name of the mapping to be used by the Dozer. This argument will be used for converting from SourceClass to DestinationClass.
While doing reverse conversion means conversion form DestinationClass to SourceClass we have to add PRIME to name of mapping.

SourceClass sourceClass = (SourceClass) mapper.map (destinationClass, SourceClass.class,”caseAPRIME”);

Usecase 2 [Complex conversion of source object into destination object.]

Let’s see a complex scenario. Say we want to exclude prop1 variable defined in SourceChildClass to be converter for caseA. So for this we have to tell the dozer to use a different mapping while converting the object belonging to collection. We could name that mapping as collCaseA, and in the field tag we will use map-id to indicate the name.

<mapping map-id="caseA">
      <class-a>package.SourceClass</class-a>
      <class-b>package.DestinationClass</class-b>
       <! -- Uses mapping named childCaseA for conversion of objects in the collection -- >
      <field map-id="collCaseA">
       <a>sourceCol</a>
       <b>destCol</b>
       <a-hint>package.SourceChildClass</a-hint>
       <b-hint>package.DesctinationChildClass</b-hint>
      </field>
 </mapping>

 <mapping map-id="collCaseA">
      <class-a>package.SourceChildClass</class-a>
      <class-b>package.DestinationChildClass</class-b>
      <field-exclude>
         <a>prop1</a>
         <b>prop1</b>
      </field-exclude>
 </mapping>

In this mapping
The change done is from Usecase-1, CaseA in adding new mapping to define exclude specific field from collection conversion under < mapping map-id=”collCaseA”> tag.

Similarly for caseB we want to exclude prop2 variable define in SourceChildClass, so we call it as collCaseB.

<mapping map-id="caseB">
  <class-a>package.SourceClass</class-a>
  <class-b>package.DestinationClass</class-b>
  <field map-id="collCaseB">
   <a>sourceCol</a>
   <b>destCol</b>
   <a-hint>package.SourceChildClass</a-hint>
   <b-hint>package.DestinationChildClass</b-hint>
  </field>
  <field-exclude>
   <a>sourceStringForInteger</a>
   <b>sourceStringForInteger</b>
  </field-exclude>
</mapping>

<mapping map-id="collCaseB">
    <class-a>package.SourceChildClass</class-a>
    <class-b>package.DestinationChildClass</class-b>
    <field-exclude>
      <a>prop2</a>
      <b>prop2</b>
    </field-exclude>
</mapping>

In this mapping
The change done is from Usecase-1, CaseB in adding new mapping to define exclude specific field from collection conversion under <mapping map-id=”collCaseB”> tag.

Conversion code would remain same for Usecase 2 as in Usecase 1.

Conclusion: You have seen various cases of context based mapping conversion. For more information you can refer following resources.
• Deep Mappings
• http://dozer.sourceforge.net/
If you have any specific question, please comment back. I will try to reply with answer.

Share

Filed under Java | 10 Comments »



10 Responses to “Dozer Mapping”



    Maarten Winkels Says:
    Posted at: September 25, 2007 at 9:40 am

    Hi Amit,

    Very interesting read! I’ve looked at Dozer a few times, but never found a good use case. Normally writing a converter class seemed so much simpler than adding a new framework, learning to use it and maintaining the XML configuration. What are the situations that you feel Dozer is a viable alternative to writing the classes your self?
    I wasn’t aware of the type conversion possibilities of the framework at the time. Is this a new feature?

    Regards, Maarten

    Reply


      Sam Says:
      Posted at: September 29, 2011 at 1:22 pm

      Well I used Dozer for one of my implementation where we were using protocol to protocol transformation for one of our Identity provisioning implementation. We had a use case where we were receiving a SPML 2.0 standard message from one ERP and we need to convert the same to Oracle Identity Manager SPML 2.0 standard. As both these ERP and OIM extended the SPML 2.0 Extension API and are making heavy use of same. we were suppose to do lots of custom code to make this attribute to attribute mapping, as we a product based company we need to implement this in more generic way so that we can make the mapping in declarative way rather in Scala code. So I used modified Dozer [some code/component of Dozer API are been replaced by Scala implementation] to address the requirement.

      Reply


    Venkat Says:
    Posted at: October 31, 2007 at 7:19 pm

    Dozer will be helpful in case if your project/system has many value objects(VO) & DTO objects. You dont need to write a lengthy method in your Java Bean, Dozer will be taking care of that with help of configuration

    Reply


    Wil Palen Says:
    Posted at: October 15, 2008 at 5:18 pm

    Dozer is far from mature yet. If you have a somewhat fancy domain model that uses inheritance and you try to map collections of a supertype that contains different specialized instances Dozer falls flat on its face.

    Also, it does not handle Number Number conversions gracefully

    In general, it seems to be unable to work with inheritance

    This is a big disappointment for a product that carries a version number of 4.2.1

    Lost a couple of days on my project because of these shortcomings. In the end we couldn’t use it.

    Reply


    LP Says:
    Posted at: August 24, 2009 at 8:46 pm

    I’d say the biggest advantage of using Dozer is that it automatically produces mapping to both directions. If you don’t need that you might want to consider writing the mapper classes yourself. Dozer is kind of configuration hell.

    Reply


    Bruce Says:
    Posted at: December 29, 2009 at 11:43 pm

    Where can I go to find help with Dozer. I have a case where the source and destination classes both have a feild of the same type (MyDate) with setters and getters. Since MyDate does not have a no-argument constructor, Dozer throw and exception. I have not be able to find any information about this.

    Reply


    sishir kumar Says:
    Posted at: January 24, 2011 at 6:37 am

    This blog is very helpfull to understand about dozer….. Thanks a lot..

    Reply


    tr3pek Says:
    Posted at: December 9, 2011 at 12:48 pm

    Hi,

    Does Dozer handles cases, when we map from one class which is exact reflcecition of DB table with complex parameter key, eg:
    DataObject {
    int key_part1;
    String key_part2;
    …
    }
    then at higher tier, we have some BO:
    BusinessObject {
    ComplexKey key;
    …
    }
    and some key class:
    ComplexKey {
    int key_part1;
    String key_part2;
    }

    Reply


    Tom Says:
    Posted at: December 21, 2011 at 1:11 am

    Yes it does, with this simple mapping configuration (don’t forget the getters and setters in your classes):

    org.dozerTest.DataObject
    org.dozerTest.BusinessObject

    key_part1
    key.key_part1

    key_part2
    key.key_part2

    Reply


    Tom Says:
    Posted at: December 21, 2011 at 1:13 am

    oops… html problems:

    Yes it does, with this simple mapping configuration (don’t forget the getters and setters in your classes):

    <mapping>
    <class-a>org.dozerTest.DataObject</class-a>
    <class-b>org.dozerTest.BusinessObject</class-b>
    <field>
    <a>key_part1</a>
    <b>key.key_part1</b>
    </field>
    <field>
    <a>key_part2</a>
    <b>key.key_part2</b>
    </field>
    </mapping>

    Reply


Leave a Reply

Click here to cancel reply.


Xebia Sites

  • Xebia Corporate
  • Xebia France
  • Xebia India
  • Xebia Sweden

Categories

  • Java (311)
  • Agile (181)
  • General (136)
  • Scrum (67)
  • Architecture (64)
  • Testing (59)
  • Performance (46)
  • Middleware (56)
    • Deployment (38)
  • Xebia Labs (39)
  • SOA (31)
  • Podcast (31)
  • Project Management (28)
  • Tools (26)
  • Uncategorized (20)
  • lean architecture (20)
  • Quality Assurance (17)
  • Articles (13)
  • Requirements Management (13)
  • Virtualization (19)

Tag Cloud

    Javascript JPA implementation patterns Spring Architecture Flex Groovy Scrum Scala ACT Frameworks Maven Agile TDD agile architectuur lean architectuur SOA Java Ajax Oracle Concurrency Control Lean XML JPA product owner Grails lean architecture Eclipse Hibernate Moving to India Xebia

Archives

  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
Avatars by Sterling Adventures