Blog

Dozer Mapping

24 Sep, 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.
[java]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;

}[/java]
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.
[java]
public class SourceChildClass {
private String prop1;
private String prop2;
private String prop3;

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

}[/java]
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)
[xml]
package.SourceClass
package.DestinationClass

sourceCol
destCol
package.SourceChildClass
package.DestinationChildClass

[/xml]
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).
[xml]
package.SourceClass
package.DestinationClass

sourceCol
destCol
package.SourceChildClass
package.DestinationChildClass
[/xml]
[xml]
sourceStringForInteger
sourceStringForInteger

[/xml]
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
[java]DestinationClass destinationClass = (DestinationClass) mapper.map (sourceClass, DestinationClass.class,”caseA”);[/java]
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.
[xml]
package.SourceClass
package.DestinationClass

sourceCol
destCol
package.SourceChildClass
package.DesctinationChildClass

[/xml]
[xml]

package.SourceChildClass
package.DestinationChildClass

prop1
prop1

[/xml]
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.
[xml]
package.SourceClass
package.DestinationClass

sourceCol
destCol
package.SourceChildClass
package.DestinationChildClass

sourceStringForInteger
sourceStringForInteger

[/xml]
[xml]
package.SourceChildClass
package.DestinationChildClass

prop2
prop2

[/xml]
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.

guest
17 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Maarten Winkels
14 years ago

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

Sam
Sam
10 years ago

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.

Venkat
Venkat
14 years ago

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

Wil Palen
Wil Palen
13 years ago

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.

LP
LP
12 years ago

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.

Bruce
Bruce
12 years ago

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.

sishir kumar
11 years ago

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

tr3pek
tr3pek
10 years ago

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;
}

Tom
Tom
10 years ago

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

Tom
Tom
10 years ago

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>

Ronald
Ronald
9 years ago

Hi, Im new to dozer, im mapping excel file to my java entity bean flawlessly. the thing is, i would like to display the source value to my page if theres an invalid mapping. for example, i accidentally put “ABC” to destination “integer”. there will be an conversionexception-thats ok and id like to display “Cannot convert “ABC” to integer” or somewhere along that line.

Shalini
Shalini
9 years ago

Hi… Thanks for the blog. Can you help me with dozer mapping of a String and an object having a field of type String?When I am trying to map by:
User
UserDTO
userPassword.password
userPassword
I get the following error:
Illegal object type for the method ‘setUserPassword’.
Expected types:
com.domain.UserPassword
Actual types:
java.lang.String

Rama
Rama
8 years ago

Hi have a scenario and need your valuable help in fixing it.
I want to integrate springs with dozer. Let me say I have a spring map bean in my xml file and how can I use this bean in my dozer custom converter?

Mohammed
Mohammed
7 years ago

If the sourceclass and destination has an object reference with same structure but belong to different package. Will the dozer be able to map it just by looking at the name as both having same name?

Anil
Anil
6 years ago

Hi,
Can someone help to map following scenario-
In source class i have 4 fields like
string field1
string field2
string field3
But in destination I have only 2 fields like –
string field1
string field2
So how I can do this mapping using dozer.

Andrew Jardine
Andrew Jardine
6 years ago

Hey Amit,
I’m having a problem with deep mapping of generics. Your tutorial here looks very similar to what I am trying to do, except that my nested object is a List rather than a direct object itself. I’m using Doze 5.5.1 and I have tried with both as well as with and . Neither case seems to work.
Can you help me understand how I can (deep) map a List of objects?

mak
mak
3 years ago

Anil, I know this is years later, but if someone else is looking for the solution, you can map only 2 of the 4 fields by using wildcard=”false” n the mapping definition of your dozerbeanmapping.xml, and then defining the 2 fields that you DO want to map
field1
field1
field2
field2

Explore related posts