views:

383

answers:

4

I am trying to use dozer 4.1 to map between classes. I have a source class that looks like this:

    public class initRequest{
     protected String id;
     protected String[] details
}

I have a destination class that looks like this:

public class initResponse{
       protected String id;
       protected DetailsObject detObj;
}

public class DetailsObject{
 protected List<String>  details;
}

So essentially i want the string in the details array to be populated into the List in the Details object.

I have tried a mapping like this:

<mapping wildcard="true" >
  <class-a>initRequest</class-a>
  <class-b>initResponse</class-b>   
  <field>
    <a is-accessible="true">details</a>
    <b is-accessible="true">detObj.details</b>
  </field>
</mapping>

But I get this error:

Exception in thread "main" net.sf.dozer.util.mapping.MappingException: java.lang.NoSuchFieldException: detObj.details
    at net.sf.dozer.util.mapping.util.MappingUtils.throwMappingException(MappingUtils.java:91)
    at net.sf.dozer.util.mapping.propertydescriptor.FieldPropertyDescriptor.<init>(FieldPropertyDescriptor.java:43)
    at net.sf.dozer.util.mapping.propertydescriptor.PropertyDescriptorFactory.getPropertyDescriptor(PropertyDescriptorFactory.java:53)
    at net.sf.dozer.util.mapping.fieldmap.FieldMap.getDestPropertyDescriptor(FieldMap.java:370)
    at net.sf.dozer.util.mapping.fieldmap.FieldMap.getDestFieldType(FieldMap.java:103)
    at net.sf.dozer.util.mapping.util.MappingsParser.processMappings(MappingsParser.java:95)
    at net.sf.dozer.util.mapping.util.CustomMappingsLoader.load(CustomMappingsLoader.java:77)
    at net.sf.dozer.util.mapping.DozerBeanMapper.loadCustomMappings(DozerBeanMapper.java:149)
    at net.sf.dozer.util.mapping.DozerBeanMapper.getMappingProcessor(DozerBeanMapper.java:132)
    at net.sf.dozer.util.mapping.DozerBeanMapper.map(DozerBeanMapper.java:94)

How can i map this so that it works?

A: 

I would guess that accessors (getter / setter) are missing. By the way I think that you'll also need to provide an empty constructor for DetailsObject so dozer can instanciate it.

zim2001
DetailsObject is generated using JAXB. the only method it has is: public List<String> getDetails() { if (details == null) { details = new ArrayList<String>(); } return this.details; }I don't want to change the generated code. Is there any work around?
Well as given your mapping cannot work, as there is no setter provided in your target class. BUT... maybe you could have a look here : http://dozer.sourceforge.net/documentation/xmlbeans.htmlIt explains how to map with xmlbeans as well as jaxb objects
zim2001
A: 

Problem solved...

  • is-accesible allows an object to be updated regardless of access modifier and presence of getters/setters (essential for objects generated using JAXB)

  • "dot" notation for deep mapping works to access nested objects

Combining the two is a feature that does not work in Dozer (maybe it does in a newer version)

solution... modify the xsd such that the deep mapping is not required. This is not my ideal solution but its better than writing a custom converter for every object

A: 

How did you modify your XSD to not generate getters and setters?

Jasdeep Singh
A: 

In case of JaxB, use can download and use the plugin for generating the setters. Refer to this link for more details, https://jaxb2-commons.dev.java.net/collection-setter-injector/

Aneesh