With dozer is it possible to map several fields to one field?

From my side I would recommend a little different solution if you need mapping two fields to single one and vice versa.

The Dozer has the possibility to user setters/getters as way to make mapping. On the class where you have to do it (where you have two fields and wants to map to single field) use the setters where you could provide single field from different object and on the setter/getter logic assign these two fields.

Example mapping:

<mapping type="bi-directional">
<class-a>ClassWithTwoFields</class-a>
<class-b>ClassWithSingleField</class-b>
<field>
  <a get-method="getHelperField" set-method="setHelperField" >helperField</a>
  <b>helperField</b>
</field>

Example getters/setters:

 public FieldType getHelperField() {
    if (!isNull(field1) && !isNull(field2)) {
        return field1 + field2;
    }
    return null;
}

public void setHelperField(FieldType singleField) {
    if (!isNull(singleField)) {
        this.field1 = singleField.part1();
        this.field2 = singleField.part2();
    }
}

It's quick way to deal with the problem.


I know that this is an old post, but I could not find a satisfying answer, spent a lot of time and then discovered this (I think) easy method. You can use a ConfigurableCustomConver in combination with the 'this' reference in your mapping.xml.

For example:

public class Formatter implements ConfigurableCustomConverter
{
   private String format;
   private String[] fields;

   @Override
   public Object convert(Object existingDestinationFieldValue, Object           sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
      List valueList = new ArrayList();

      for (String field : fields){
        try {
           valueList.add(sourceClass.getMethod(field).invoke(sourceFieldValue));
        }
        catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
           throw new RuntimeException("Reflection error during mapping", e);
        }
     }
     return MessageFormat.format(format, valueList.toArray());
  }

  @Override
  public void setParameter(String parameter)
  {
     String[] parameters = parameter.split("\\|");
     format = parameters[0];
     fields = Arrays.copyOfRange( parameters, 1, parameters.length);
  }
}

and in your mapping.xml:

<mapping type="one-way">
    <class-a>test.model.TestFrom</class-a>
    <class-b>test.model.TestTo</class-b>

    <field custom-converter="nl.nxs.dozer.Formatter" custom-converter-param="{0}{1}|getFirstValue|getSecondValue">
        <a>this</a>
        <b>combinedValue</b>
    </field>
</mapping>

classes:

public class TestFrom
{
   private String firstValue;
   private String secondValue;

   public String getFirstValue()
   {
      return firstValue;
   }

   public void setFirstValue(String firstValue)
   {
      this.firstValue = firstValue;
   }

   public String getSecondValue()
   {
      return secondValue;
   }

   public void setSecondValue(String secondValue)
   {
      this.secondValue = secondValue;
   } 
}
public class TestTo
{
   private String combinedValue;  

   public String getCombinedValue(){
      return combinedValue;
   } 

   public void setCombinedValue(String combinedValue){
      this.combinedValue = combinedValue;
   }
}

Tags:

Java

Dozer