Morphia List <Map >>返回嵌入式元素在查找操作时不是DBObject

我试图做这样的事情:

package org.dnylabs.kosh.data; import java.net.UnknownHostException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.google.code.morphia.Datastore; import com.google.code.morphia.Morphia; import com.google.code.morphia.annotations.Entity; import com.google.code.morphia.annotations.Id; import com.mongodb.Mongo; import com.mongodb.MongoException; @Entity public class Temp { @Id String _id; List<Map> strings; public Temp(){ strings=new LinkedList<Map>(); } public static void main(String []args) throws UnknownHostException, MongoException{ Mongo mongo=null; Morphia morphia=null; Datastore ds=null; mongo = new Mongo(); morphia = new Morphia(); morphia.map(Temp.class); ds = morphia.createDatastore(mongo, "test"); Temp t = new Temp(); t._id ="hi"; Map m = new HashMap(); m.put("Hi","1"); m.put("Hi2",2); t.strings.add(m); ds.save(t); t=ds.get(t); ds.ensureIndexes(); } } 

当我尝试执行findAll(9操作我得到此exception:

 Caused by: java.lang.RuntimeException: org.mongodb.morphia.mapping.MappingException: Embedded element isn't a DBObject! How can it be that is a class java.lang.String at org.mongodb.morphia.mapping. here`dedMapper.fromDBObject(EmbeddedMapper.java:172) at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:602) at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:559) at org.mongodb.morphia.mapping.EmbeddedMapper.readMapOrCollectionOrEntity(EmbeddedMapper.java:256) at org.mongodb.morphia.mapping.EmbeddedMapper.readCollection(EmbeddedMapper.java:203) at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:144) ... 16 more 

经过多次尝试,我发现问题是嫁接地图。

谁能帮我理解我错在哪里? 声明似乎是正确的。

Morphia将Map视为对另一个文档的DB引用,而不是将其视为嵌入式类并视为文档。 解决方案是注释Map @Embedded,但这是不可能的,因为你无法编辑Map类。

有一种方法可以通过创建另一个类并将Map定义为此类的属性并将其注释为@Embedded来实现与您尝试的类似的操作。

更改Temp类:

 public class Temp { @Id String _id; @Embedded // CHANGE HERE List strings; // CHANGE HERE public Temp(){ strings=new LinkedList(); // CHANGE HERE } public static void main(String...args) throws UnknownHostException, MongoException{ Mongo mongo=null; Morphia morphia=null; Datastore ds=null; mongo = new Mongo(); morphia = new Morphia(); morphia.map(Temp.class); ds = morphia.createDatastore(mongo, "test2"); Temp t = new Temp(); t._id ="hi"; MapProxy mp = new MapProxy(); // CHANGE HERE mp.m.put("Hi","1"); // CHANGE HERE mp.m.put("Hi2",2); // CHANGE HERE t.strings.add(mp); // CHANGE HERE ds.save(t); t=ds.get(t); ds.ensureIndexes(); } } 

并创建一个新类:

 @Embedded public class MapProxy { public Map m = new HashMap(); } 

我已经标记了我所做的改变。

它产生的结构是这样的:

 { "_id" : "hi", "className" : "YOUR CLASS NAME HERE", "strings" : [ { "m" : { "Hi" : "1" , "Hi2" : 2 } } ] } 

所以这就是正在发生的事情。 Morphia将尝试序列化类中的任何非瞬态非静态字段。 现在,如果该字段是使用@Entity注释的类型,则morphia将通过并内省事物并设置正确的映射。 如果没有,在构造DBObject以交给Java驱动程序时,它将是一些默认的基本序列化程序。 在这种情况下,您有一个原始类型( Object ),而morphia必须对其类型和结构做出某些假设。 在发现您的结构违反了这些假设后,它就会失败。 这就是为什么当你像亚历克斯所展示的那样打破局面时它会起作用。 这可能是以这种或那种方式修复的,但是由于我打算从上到下重做映射代码,我预计不会尝试在当前代码中修复此问题。 希望这可以帮助。