Search code examples
javaorika

Orika: CustomConverter not called on null values


I'm using Orika 1.4.6 and I'd like to use a CustomConverter to map one of my fields. When the source field is null, the converter doesn't seem to be called. Here is my code:

class From {
    String source;
}

class To {
    String destination = "defaultValue";
}

public class Mapper extends ConfigurableMapper {

  private class MyConverter extends CustomConverter<String, String> {

    @Override
    public String convert(String source, Type<? extends String> destinationType) {
      if (null == source) {
        return "NULL!";
      }
      return "->" + source + "<-";
    }
  }

  @Override
  protected void configure(MapperFactory factory) {

    factory.getConverterFactory().registerConverter("converter", new MyConverter());

    factory.classMap(From.class, To.class)

        .fieldMap("source", "destination")
        .mapNulls(true)
        .converter("converter")
        .add()

    .register();
  }
}

If I map the following object:

From from = new From(); //from.source == null

Mapper mapper = new Mapper();
To to = mapper.map(from, To.class);

System.out.println(to.destination);

I expect the following output:

NULL!

However I get the following:

null

which suggests that the converter isn't called at all and the null value is simply copied, because of

.mapNulls(true)

If I now set

.mapNulls(false)

the problem remains the same, as the null value in the source field is ignored which leaves the destination field unchanged (in this case with the value "defaultValue").

It would for example be possible to use the "customize" method in combination with a CustomMapper. However this solution is a lot more complex in my real application and therefore the solution with the CustomConverter seems much more appropriate.

Does anyone know where the problem is in this specific example?

Cheers, Robert


Solution

  • The observed behaviour is intentional.

    Instead of using a custom converter that handles null values, it is possible to create an ObjectFactory that handles object creation. Here we can set the default values and override them if needed (i.e. if a non-null object is mapped) in the custom converter. Note that here we have to set

    .mapNulls(false)
    

    for this to work.

    Thanks to Elaatifi from Orika for this solution!