We are using org.mongodb.morphia to convert objects BasicDBObjects before persistence. One issue encountered is that in some cases the object to convert contains an empty HashMap whose size is 0, after conversion, the HashMap is converted to null. So NullPointerException throw in later accessing. I want to ask experts for help, Is there any way to avoid this? I mean, after conversion, it's still an HashMap with size 0.
Part of the class to be converted:
public class ProjectServiceAdapterConfig {
@NotNull
private String serviceAdapterId;
@NotNull
private String projectId;
@Embedded
@Flatten
private Map<String, Map<String, String>> connections = new HashMap<>();
//...... setter and getter skipped here
}
code for conversion:
// create a mapper with default MapperOptions
private Mapper createMapper() {
return new Mapper();
}
ReplaceableItem objectToItem(final ProjectServiceAdapterConfig obj) {
final Mapper mapper = createMapper();
final MappedClass mc = mapper.getMappedClass(obj.getClass());
final Map<String, Object> map = mapper.toDBObject(obj).toMap();
}
the obj is created in other place. After some debug, I found that, the obj contains an empty Map(following data copied from IntelliJ IDEA debugger):
connections = {java.util.LinkedHashMap@8890} size = 1
[0] = {java.util.LinkedHashMap$Entry@8894}"accounts" -> size = 0
key: java.lang.String = {java.lang.String@8895}"accounts"
value: java.util.LinkedHashMap = {java.util.LinkedHashMap@8896} size = 0
and the one after converted:
[2] = {java.util.LinkedHashMap$Entry@8910}"connections" -> size = 1
key: java.lang.String = {java.lang.String@8911}"connections"
value: com.mongodb.BasicDBObject = {com.mongodb.BasicDBObject@8912} size = 1
[0] = {java.util.LinkedHashMap$Entry@8923}"accounts" -> null
key: java.lang.String = {java.lang.String@8895}"accounts"
value: = null
As you can see , it's converted to null which we try to avoid. Thanks
I assume I cannot avoid it without customizing the MapOfValuesConverter. See from the source code that the empty map will be always converted to null:
@Override
public Object encode(Object value, MappedField mf) {
if (value == null)
return null
Map<Object, Object> map = (Map<Object, Object>) value;
if ((map != null) && (map.size() > 0)) {
Map mapForDb = new HashMap();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
String strKey = converters.encode(entry.getKey()).toString();
mapForDb.put(strKey, converters.encode(entry.getValue()));
}
return mapForDb;
}
return null;
}