Non-trivial Dozer mappings

teabot picture teabot · Dec 16, 2009 · Viewed 7.1k times · Source

I'm struggling to get Dozer to bend to my will for something that I feel should be quite simple. I have two similar models that I wish to map between, however one has a 'deeper' hierarchy than the other and this is causing me problems when dealing with collections. Consider the following classes:

Source classes:

class Foo {
    String id;
    NameGroup nameGroup; 
    // Setters/Getters
}

class NameGroup {
    private List<Name> names;
    // Setters/Getters
}

class Name {
    private String nameValue;
    // Setters/Getters
}

Destination classes:

class Bar {
    private String barId;
    private BarNames barNames;
    // Setters/Getters
}

class BarNames {
    private List<String> names;
    // Setters/Getters
}

Now I'd like the following one-way mappings:

Foo.id -> Bar.barId // Simple enough

But I then need:

Foo.nameGroup.names.nameValue -> Bar.barNames.names

So each Name instance in Foo.nameGroup.names should result in a String being added to the BarNames.names list. Is this possible?

Answer

pjmyburg picture pjmyburg · Jan 4, 2010

This can easily be done with Dozer as long as your "Name" class contains a String constructor.

A quote from the Dozer docs (http://dozer.sourceforge.net/documentation/simpleproperty.html):

Data type coversion is performed automatically by the Dozer mapping engine. Currently, Dozer supports the following types of conversions: (these are all bi-directional)

...

String to Complex Type if the Complex Type contains a String constructor

...

I have tested this with your classes as above (I was stuck with the same problem) and it works perfectly. Here is the mapping I used:

<mapping>
  <class-a>com.test.bar.Bar</class-a>
  <class-b>com.test.foo.Foo</class-b>
  <field>
    <a>barId</a>
    <b>id</b>
  </field>
  <field>
    <a>barNames.names</a>
    <b>nameGroup.names</b>
    <a-deep-index-hint>java.lang.String</a-deep-index-hint>
    <b-deep-index-hint>com.test.foo.Name</b-deep-index-hint>
  </field>
</mapping>