我们正在使用org.mongodb.morphia在持久化之前转换对象BasicDBObjects。遇到的一个问题是,在某些情况下,要转换的对象包含一个大小为0的空HashMap,转换后,HashMap将转换为null。所以NullPointerException会在以后访问时抛出。我想请求专家帮忙,有什么方法可以避免这种情况吗?我的意思是,转换后,它仍然是一个大小为0的HashMap。
要转换的类的一部分:
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
}
转换代码:
// 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();
}
obj是在其他地方创建的。经过一些调试,我发现,obj包含一个空Map(跟随从IntelliJ IDEA调试器复制的数据):
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
和转换后的那个:
[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
如您所见,它被转换为null,我们尽量避免。 感谢
答案 0 :(得分:1)
我假设在没有自定义MapOfValuesConverter的情况下我无法避免它。从源代码中看,空映射将始终转换为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;
}
答案 1 :(得分:0)
在调用morphia.mapPackage()之前,请执行以下操作:
morphia.getMapper().getOptions().storeEmpties = true;
这应该可能会映射回你的空地图。
答案 2 :(得分:0)
如果morphia.getMapper().getOptions().setStoreEmpties(true);
不适合您,另一种解决方案是使用@PostLoad
annotation检查您是否有空集合并在必要时创建一个空集合。
import java.util.*;
import org.mongodb.morphia.annotations.*;
import org.bson.types.ObjectId;
@Entity
public class Model {
@Id
private ObjectId id;
private Map<String, String> map;
protected Model() {}
public Model(HashMap<String, String> map) {
super();
setMap(map);
}
public void setMap(HashMap<String, String> map) {
this.map = map;
checkForNullMap();
}
@PostLoad
private void checkForNullMap() {
if (map == null) {
map = new HashMap<String, String>();
}
}
}