'Easiest Way for MapStruct to map a default for all properties of an object
Suppose I have a target object
MyObject {
boolean myBoolean;
int myInt;
...
}
where fields myBoolean and myInt are required (i.e., if you try to call build() on the Builder for MyObject without setting those fields, an error is thrown).
I can't seem to find a simple way to tell MapStruct to set defaults for each field in my object to ensure all required fields have been set, despite trying a number of MapStruct constructs that seem related to this functionality:
- According to documentation, NullValuePropertyMappingStrategy is only for update methods.
- If I try to set nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT on the @Mapper level, MapStruct won't actually set the default for each field. The generated code looks like (e.g.):
.
Builder target = new Target.builder();
if (source != null) {
if ( source.isMyBoolean() != null ) {
target.withMyBoolean( source.isMyBoolean() );
}
...
}
target.build();
In the above the field myBoolean in Source is a Boolean (vs. a boolean). As you can see, if source.isMyBoolean == null then target.withMyBoolean(...) will not be called, causing an error.
The only way I have found to get around this is to specify a NullValueMappingStrategy or a defaultValue on the individual @Mapping level for each required property which is very verbose.
Wondering if anyone knows a better way to accomplish this.
Solution 1:[1]
If your target object has primitives your fields has default value, no ?
As say in the doc NullValueMappingStrategy.RETURN_DEFAULT work on bean, list ... but you are right not on Integer, String, Boolean.
If I have :
public class MyObjectDTO {
Boolean myBoolean;
Integer myInt;
String myString;
TempObjectDTO tempObjectDTO;
}
public class MyObject {
Boolean myBoolean;
Integer myInt;
String myString;
TempObject tempObject;
}
After mapping MyObject <--> MyObjectDTO :
- TempObject/TempObjectDTO has default value
- all other objects have null value.
To prevent this I have created mapping method for String, Integer, Boolean in the mapper and use a factory because Integer and Boolean doesn't have a default constructor.
Mapper:
@Mapper(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT,//
uses = { DefaultFactory.class })
public interface MyObjectMapper {
@Mapping(source = "tempObjectDTO", target = "tempObject")
MyObject fromDTO(MyObjectDTO myObjectDTO);
@Mapping(source = "tempObject", target = "tempObjectDTO")
MyObjectDTO toDTO(MyObject myObject);
TempObject fromDTO(TempObjectDTO dto);
TempObjectDTO fromDTO(TempObject tempObject);
String from(String string);
Integer from(Integer integer);
Boolean from(Boolean booleanObject);
}
Factory:
public class DefaultFactory {
public Integer createInteger() {
return new Integer(100);
}
public Boolean createBoolean() {
return new Boolean(true);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | lmoal |
