我正在尝试学习MongoDB和Morphia,并且我已经用Java创建了一个示例应用程序。 但是在执行聚合时,我得到“ObjectId的无效十六进制表示”错误。
Morphia版本是1.3.2
实体:Address.java
@Entity
public class Address {
@Id
@Property("id")
protected ObjectId id;
private String street;
private String building;
private String pin;
}
示例文档:
{
"_id" : ObjectId("58fcb704c1d24e05ce5851cb"),
"building" : "SGV",
"street" : "Galaxy Heights",
"pin" : "411017"
}
AddressDAO.java:
public class AddressDAO extends BasicDAO<Address, ObjectId>{
public AddressDAO(Class<Address> entityClass, Datastore ds) {
super(entityClass, ds);
}
public List<Address> getByGroupedData(String pin) {
Query<Address> query = createQuery().field("pin").equal(pin);
Iterator<Address> pipeline = getDatastore().createAggregation(Address.class)
.match(query)
.group(Group.id(Group.grouping("building"))).out(Address.class);
while(pipeline.hasNext()) {
System.out.println(pipeline.next());
}
return null;
}
}
在AddressDAO.java中调用'pipeline.next()'时,我得到了异常:
java.lang.IllegalArgumentException: invalid hexadecimal representation of an ObjectId: [{ "building" : "Galaxy Heights"}]
at org.bson.types.ObjectId.parseHexString(ObjectId.java:550)
at org.bson.types.ObjectId.<init>(ObjectId.java:240)
at org.mongodb.morphia.converters.ObjectIdConverter.decode(ObjectIdConverter.java:32)
at org.mongodb.morphia.converters.Converters.fromDBObject(Converters.java:124)
at org.mongodb.morphia.mapping.ValueMapper.fromDBObject(ValueMapper.java:20)
at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:844)
at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:282)
at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:193)
知道我在这里缺少什么吗?
答案 0 :(得分:2)
我认为问题出在$out
阶段。它使用_id字段创建新集合作为building
值。
现在,当您尝试将其映射回Address
对象时,_id
对象的ID被定义为对象ID,这会导致错误。
因此修复方法是使用$projection
来抑制最终响应中的_id
字段,以便$ out阶段创建一个新的Object ID。
尝试这样的事情。
Iterator<Address> pipeline = getDatastore().createAggregation(Address.class)
.match(query)
.group(Group.id(Group.grouping("building")))
.project(Projection.projection("_id").suppress(), Projection.projection("building", "$_id"))
.out(Address.class);
旁注:你可能应该为新的集合映射到新的pojo对象。