2

I'm trying to use Dozer to automatically map from primitive classes to each other. At the end, the code might end up looking like this.

Boolean resultBoolean = mapper.map("true", Boolean.class);

While Dozer does support mapping String to Boolean when in a bean, it seems mapping directly to Boolean produces the following exception.

org.dozer.MappingException: java.lang.NoSuchMethodException: java.lang.Boolean.<init>()
at org.dozer.util.MappingUtils.throwMappingException(MappingUtils.java:88)
at org.dozer.factory.ConstructionStrategies$ByConstructor.newInstance(ConstructionStrategies.java:261)
at org.dozer.factory.ConstructionStrategies$ByConstructor.create(ConstructionStrategies.java:245)
at org.dozer.factory.DestBeanCreator.create(DestBeanCreator.java:65)
at org.dozer.MappingProcessor.map(MappingProcessor.java:178)
at org.dozer.MappingProcessor.map(MappingProcessor.java:125)
at org.dozer.MappingProcessor.map(MappingProcessor.java:120)
at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:111)

...

Caused by: java.lang.NoSuchMethodException: java.lang.Boolean.<init>()
at java.lang.Class.getConstructor0(Class.java:2706)
at java.lang.Class.getDeclaredConstructor(Class.java:1985)
at org.dozer.factory.ConstructionStrategies$ByConstructor.newInstance(ConstructionStrategies.java:257)
... 32 more

It is clear that Dozer is trying to instantiate the Boolean itself. I'm able to create a customer DozerConverter to convert Boolean to String, but I don't want to re-implement the code that Dozer already has. Is there any way to get Dozer to map to and from primitive types directly?

Arthur Maltson
  • 5,760
  • 4
  • 30
  • 33

1 Answers1

0

You could use org.dozer.converters.PrimitiveOrWrapperConverter instead of org.dozer.DozerBeanMapper :

import org.dozer.converters.DateFormatContainer;
import org.dozer.converters.PrimitiveOrWrapperConverter;

public class DozerPrimitiveMapping {


    public static void main(String[] args) {

        PrimitiveOrWrapperConverter primitiveConverter = new PrimitiveOrWrapperConverter();
        //DateFormatContainer is not needed in this String-to-Boolean use case, but the converter would throw an error if it was null
        DateFormatContainer dateFormatContainer = new DateFormatContainer("");
        Boolean booleanResult= (Boolean) primitiveConverter.convert("true", Boolean.class, dateFormatContainer);
        System.out.println("Boolean result from dozer: "+booleanResult);
    }
}

Or wrap it all up in a custom converter:

package my.dozer.test;

import org.dozer.CustomConverter;
import org.dozer.converters.DateFormatContainer;
import org.dozer.converters.PrimitiveOrWrapperConverter;

public class DozerPrimitiveConverter implements CustomConverter {

    private final PrimitiveOrWrapperConverter primitiveConverter = new PrimitiveOrWrapperConverter();
    //DateFormatContainer is not needed in this String-to-Boolean use case, but the converter would throw an error if it was null
    private final DateFormatContainer dateFormatContainer = new DateFormatContainer("");

    @Override
    public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
        Boolean booleanResult = (Boolean) primitiveConverter.convert(sourceFieldValue, Boolean.class, dateFormatContainer);
        return booleanResult;
    }

}

And configure the converter like it is in this example configuration file dozer-primitive-mapping.xml :

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">

    <configuration>
        <custom-converters>
          <converter type="my.dozer.test.DozerPrimitiveConverter" >
              <class-a>java.lang.String</class-a>
              <class-b>java.lang.Boolean</class-b>
          </converter>
        </custom-converters>
    </configuration>

</mappings>

Example class to run the mapping with using the custom converter:

package my.dozer.test;

import java.io.InputStream;
import org.dozer.DozerBeanMapper;

public class DozerPrimitiveConverterApp {

    public static void main(String[] args) {
        DozerBeanMapper mapper = new DozerBeanMapper();
        InputStream is = DozerPrimitiveConverterApp.class.getClassLoader().getResourceAsStream("dozer-primitive-mapping.xml");
        mapper.addMapping(is);

        Boolean booleanValue = mapper.map("false", Boolean.class);
        System.out.println("Boolean result from dozer with custom converter: " + booleanValue);

    }
}
Vincent
  • 470
  • 6
  • 13