Search code examples
javadozer

Dozer 5.3.2. Programmatically set custom converters?


How do I programmatically set custom converter for dozer? The following code doesn't work:

Custom Converter implementation:

class ConverterImpl extends DozerConverter<A, B> {

ConverterImpl() {
    super(A.class, B.class);
}

@Override
public B convertTo(A source, B destination) {
    return destination;
}

@Override
public A convertFrom(B source, A destination) {
    return destination;
}
}

Test code:

DozerBeanMapper mapper = new DozerBeanMapper();
mapper.setCustomConverters(Collections.<CustomConverter>singletonList(new ConverterImpl()));
A a = new A(); 
B b = mapper.map(a, A.class);  

After running the code above, custom converter doesn't get invoked. What is wrong?


Solution

  • Looks like you have to actually add a specific mapping, and unfortunately you can only specify field-level converters, not class-level converters, using the programmatic API. So if you wrap the A and B classes in container classes, you can specify a mapping for the A and B fields.

    For example the following verbose code works as expected:

    public class DozerMap {
    
       public static class ContainerA {
          private A a;
          public A getA() { return a; }
          public void setA(A a) { this.a = a; }
       }
    
       public static class ContainerB {
          private B b;
          public B getB() { return b; }
          public void setB(B b) { this.b = b; }
       }
    
       private static class A { };
    
       private static class B { };
    
       static class ConverterImpl extends DozerConverter<A, B> {
    
          ConverterImpl() {
             super(A.class, B.class);
          }
    
          @Override
          public B convertTo(A source, B destination) {
             Logger.getAnonymousLogger().info("Invoked");
             return destination;
          }
    
          @Override
          public A convertFrom(B source, A destination) {
             Logger.getAnonymousLogger().info("Invoked");
             return destination;
          }
       }
    
       public static void main(String[] args) {
    
          DozerBeanMapper mapper = new DozerBeanMapper();
          mapper.setCustomConverters(Collections.<CustomConverter> singletonList(new ConverterImpl()));
          BeanMappingBuilder foo = new BeanMappingBuilder() {
    
             @Override
             protected void configure() {
                mapping(ContainerA.class, ContainerB.class).fields("a", "b", FieldsMappingOptions.customConverter(ConverterImpl.class));
             }
          };
          mapper.setMappings(Collections.singletonList(foo));
          ContainerA containerA = new ContainerA();
          containerA.a = new A();
          ContainerB containerB = mapper.map(containerA, ContainerB.class);
       }
    }