I have deep property mapping in my application (from domain objects to DTO, and the reverse), similar to next example:
...
<field>
<a>employee.id</a>
<b>employeeId</a>
</field>
...
When Dozer converts Domain to DTO, it maps employee.id
to employeeId
, and that is ok.
When Dozer converts DTO to Domain, it maps employeeId
to a new Employee instance with id=employeeId.
I want to create some logic for this deep property mapping, but i just can't figure out solution. I tried to implement CustomConverter
(or extend DozerConverter
) but Dozer passes me Integer type as source and destination class(and expect Integer as result).
EDIT:
More precisely, what i need is to map employee
in Domain to null
if employeeId
in DTO is 0.
Is this possible?
Any advice?
EDIT ACCORDING TO ANSWERS: I solve problem with field-level custom converter. Instead of earlier, above mentioned, mapping, now i have something like this...
...
<field custom-converter="ManyToOneIdMapper" custom-converter-param="id">
<a>employee</a>
<b>employeeId</b>
</field>
...
In ManyToOneIdMapper i have...
public class ManyToOneIdMapper implements ConfigurableCustomConverter{
//...
//parameter field declaration, setParameter and getParameter implementations etc.
//...
public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue,
Class<?> destinationClass, Class<?> sourceClass) {
try {
if(sourceClass.equals(Integer.class)){
Integer src=(Integer)sourceFieldValue;
if(src==null || src==0)
return null;
String setterName=formatMethodName("set", getParameter());
Method setterMethod=destinationClass.getMethod(setterName, Integer.class);
Object instance=destinationClass.newInstance();
setterMethod.invoke(instance, src);
return instance;
}else{
if(sourceFieldValue==null)
return 0;
String getterName=formatMethodName("get", getParameter());
Method getterMethod=sourceClass.getMethod(getterName);
Object instance=getterMethod.invoke(sourceFieldValue);
return instance;
}
} catch (Exception e){}
return null;
}
/**
* @return - method name (most often setter or getter) according to fieldName.
* For example formatMethodName("get", "id") returns "getId"
*/
protected String formatMethodName(String methodPrefix, String fieldName){
String trimmedFieldName=fieldName.trim();
String firstLetter=String.valueOf(trimmedFieldName.charAt(0));
String capitalizedFirstLetter=firstLetter.toUpperCase();
String methodName=methodPrefix+""+capitalizedFirstLetter+""+fieldName.substring(1);
return methodName;
}
custom-converter-param
is just name of id-field in Domain object. With that name, i just call setter or getter method in my converter. Probably, it is not the happiest solution, but it works for my problem scenario.
You want a CustomConverter
to map the parent object, for example:
Domain
class PersonA {
...
int employeeId;
...
}
DTO
class PersonB {
...
Employee employee;
...
}
class Employee {
...
int id;
...
}
You want to map the two classes PersonA
and PersonB
using a CustomConverter
, this will let you construct them what ever way you want.