Search code examples
getterdozercomplextypedictionary

Dozer, how to map from java.util.Map to complex type?


I'd like to map from a java.util.Map to a complex type, let's call it Abc.

<mapping>
  <class-a>java.util.Map</class-a>
  <class-b bean-factory="xyz.AbcBeanFactory" factory-bean-id="AbcBeanFactory">
    xyz.Abc
  </class-b>
  <field>
    <a>Name</a>
    <b>companyName</b>
  </field>
</mapping>

With that I get this error (which is comprehensible): org.dozer.MappingException: No read or write method found for field (Name) in class (interface java.util.Map)

Ok, how do I map from a java.util.Map that has an entry with the key 'Name'? Do I have to create a wrapper object that holds that java.util.Map and provide getters/setters for each entry in that map that I want to map?


Solution

  • You can find details for mapping a Map in the Dozer documentation. You need to provide a key not a plain field. Here is an example:

    Class Abc:

    package com.test;
    
    public class Abc {
        private String companyName;
        private String companyAddress;
    
        public String getCompanyName() {
            return companyName;
        }
    
        public void setCompanyName(String companyName) {
            this.companyName = companyName;
        }
    
        public String getCompanyAddress() {
            return companyAddress;
        }
    
        public void setCompanyAddress(String companyAddress) {
            this.companyAddress = companyAddress;
        }
    }
    

    Mapping file:

    <mapping>
        <class-a>java.util.Map</class-a>
        <class-b>com.test.Abc</class-b>
        <field>
            <a key="name">this</a>
            <b>companyName</b>
        </field>
        <field>
            <a key="address">this</a>
            <b>companyAddress</b>
        </field>
    </mapping>
    

    Test code:

    Map<String, String> map = new HashMap<String, String>();
    map.put("name", "Company Inc.");
    map.put("address", "XYZ Commercial Street");
    
    Abc destObject =  dozerMapper.map(map, Abc.class);