如何避免在morphia中将空HashMap转换为null?

时间:2014-01-22 07:32:44

标签: mongodb morphia

我们正在使用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,我们尽量避免。 感谢

3 个答案:

答案 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>();
        }
    }
}