2014-01-28 26 views
1

我一直在使用Morphia,因为我在使用Spring Data for Mongodb的参考文档时遇到了问题。下面是我拥有的数据和代码的快照...使用Morphia检索引用的文档会返回奇怪的错误

这里是我的用户和组班(getter和setter方法省略)

用户类别

import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 

import org.mongodb.morphia.annotations.Entity; 
import org.mongodb.morphia.annotations.Id; 
import org.mongodb.morphia.annotations.Reference; 



@Entity(value="users") 
public class User { 

@Id 
    private String id; 
private String username; 
private String firstname; 
private String lastname; 
private String email; 
private long cellnumber; 
private Date datejoined; 
private boolean active; 
private Account account; 

@Reference(value="usergroups", lazy=true) 
private List<Group> usergroups = new ArrayList<>(); 

} 

的组类。

@Entity(value="groups") 
public class Group { 
@Id 
private String id; 
private String name; 
private String description; 
private long creationdate; 

@Reference 
private User user; 

} 

我现在正在主要方法中运行以下方法,名为scenario1()和scenario2()。

private void scenario1() { 

    User newUser = setupUser(new User()); 
    datastore.save(newUser); 
    Query<User> query = datastore.createQuery(User.class) 
      .field("firstname").equal("Jome"); 
    User user = query.get(); 

    Account account = new Account(); 
    account.setBalance(0.0); 
    account.setSmsvalue(0.18); 

    UpdateOperations<User> update = datastore 
      .createUpdateOperations(User.class); 
    update.set("account", account); 

    user.setAccount(account); 
    datastore.save(user); 
    List<Group> groups = query.get().getUsergroups(); 

    Group group1 = new Group(); 
    group1.setCreationdate(new Date().getTime()); 
    group1.setDescription("test group for first user"); 
    group1.setName("Group One"); 
    group1.setUser(query.get()); 
    datastore.save(group1); 
    groups.add(group1); 
    update.add("usergroups", group1); 
    datastore.update(query, update); 

    Group group2 = new Group(); 
    group2.setCreationdate(new Date().getTime()); 
    group2.setDescription("Another test group for first user"); 
    group2.setName("Group Two"); 
    group2.setUser(query.get()); 
    datastore.save(group2); 
    groups.add(group2); 

    update.add("usergroups", group2); 

    datastore.update(query, update); 

    System.out.println(user); 
    List<Group> savedgroups = user.getUsergroups(); 
    System.out.println(savedgroups); 
} 

这是低于输出

User [id=52e8894ef148a7f866b9f1ac, username=jomski2013, firstname=Jome, lastname=Akpoduado, [email protected], cellnumber=123456789] 
[Group [id=52e8894ef148a7f866b9f1ad, name=Group One, description=test group for first user, creationdate=1390971214880, owner=User [id=52e8894ef148a7f866b9f1ac, username=jomski2013, firstname=Jome, lastname=Akpoduado, [email protected], cellnumber=123456789]], Group [id=52e8894ef148a7f866b9f1ae, name=Group Two, description=Another test group for first user, creationdate=1390971214884, owner=User [id=52e8894ef148a7f866b9f1ac, username=jomski2013, firstname=Jome, lastname=Akpoduado, [email protected], cellnumber=123456789]]] 

并从蒙戈控制台视图

> db.users.find().pretty() 
{ 
"_id" : ObjectId("52e8894ef148a7f866b9f1ac"), 
"account" : { 
    "balance" : 0, 
    "smsvalue" : 0.18 
}, 
"active" : true, 
"cellnumber" : NumberLong("123456789"), 
"className" : "org.imanmobile.sms.core.domain.User", 
"datejoined" : ISODate("2014-01-29T04:53:34.746Z"), 
"email" : "[email protected]", 
"firstname" : "Jome", 
"lastname" : "Akpoduado", 
"password" : "$2a$10$c0SAy7eJZv06eqmAWQNUP.YrXtB7tDOdi11lkZqlAVgzVGU9RCbCS", 
"usergroups" : [ 
    DBRef("groups", "52e8894ef148a7f866b9f1ad"), 
    DBRef("groups", "52e8894ef148a7f866b9f1ae") 
], 
"username" : "jomski2013" 
} 

> db.groups.find().pretty() 
{ 
"_id" : ObjectId("52e8894ef148a7f866b9f1ad"), 
"className" : "org.imanmobile.sms.core.domain.Group", 
"name" : "Group One", 
"description" : "test group for first user", 
"creationdate" : NumberLong("1390971214880"), 
"user" : DBRef("users", "52e8894ef148a7f866b9f1ac") 
} 
{ 
"_id" : ObjectId("52e8894ef148a7f866b9f1ae"), 
"className" : "org.imanmobile.sms.core.domain.Group", 
"name" : "Group Two", 
"description" : "Another test group for first user", 
"creationdate" : NumberLong("1390971214884"), 
"user" : DBRef("users", "52e8894ef148a7f866b9f1ac") 
} 

然而,当我随后运行scenario2()

private void scenario2() { 
    Query<User> query = datastore.createQuery(User.class); 

    User user = query.field("username").equal("jomski2013").get(); 
    System.out.println("Number of groups: " + user.getUsergroups().size()); 
} 

我得到错误...

Caused by: org.mongodb.morphia.mapping.MappingException: The reference({ "$ref" : "groups", "$id" : "52e8894ef148a7f866b9f1ad" }) could not be fetched for org.imanmobile.sms.core.domain.User.usergroups 
at org.mongodb.morphia.mapping.ReferenceMapper.resolveObject(ReferenceMapper.java:304) 
at org.mongodb.morphia.mapping.ReferenceMapper$1.eval(ReferenceMapper.java:243) 
at org.mongodb.morphia.utils.IterHelper.loopOrSingle(IterHelper.java:89) 
at org.mongodb.morphia.mapping.ReferenceMapper.readCollection(ReferenceMapper.java:239) 
at org.mongodb.morphia.mapping.ReferenceMapper.fromDBObject(ReferenceMapper.java:163) 
at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:602) 
at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:584) 
at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:294) 
at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:71) 
at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:58) 
at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:53) 
at org.mongodb.morphia.query.QueryImpl.get(QueryImpl.java:408) 
at org.imanmobile.sms.PlayClass.scenario2(PlayClass.java:35) 
at org.imanmobile.sms.PlayClass.run(PlayClass.java:29) 
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:644) 

我的问题是,为什么是吗啡能够获取该是围绕保存第一次组,但随后不进行?有什么不同,或者我真的应该寻找什么或缺少什么?

回答

1

还有就是用户组之间的类型不匹配DBRef阵列和这些所引用的文件:

"usergroups" : [ 
    DBRef("groups", "52e82c05f148a7310a899a50"), 
    DBRef("groups", "52e82c05f148a7310a899a4f") 
] 

$ref.id是类型字符串的

而在组集合中_id是类型的ObjectId

"_id" : ObjectId("52e82c05f148a7310a899a4f")

"_id" : ObjectId("52e82c05f148a7310a899a50")

这就是为什么引用无法提取。

您不必运行辅助查询,这是由Morphia自动完成的。

很难确定造成这种不匹配的原因。难道是最初在你的Java Group类中你有 private String ObjectId;这个字段,这个字段曾被用于插入,后来又改为private String id;

在任何情况下要解决这个问题,你就必须包装内usergroups阵列的$ref.id值与ObjectId解决这个问题:

"usergroups" : [ 
    DBRef("groups", ObjectId("52e82c05f148a7310a899a50")), 
    DBRef("groups", ObjectId("52e82c05f148a7310a899a4f")) 
] 

您还必须相应地改变你的Group映射(设置id财产ObjectId

如果你要离开的事情因为是(把一切都为字符串),刚刚降你的数据库(我猜你只是尝试),并从新鲜

启动
+0

我仍然遇到同样的问题。我编辑了原始问题并添加了更多代码。奇怪的是,当我运行名为scenario1()的方法时,我得到了代码后面的结果。运行该方法,scenario2()仍然会给出我最初讨论的参考错误。 – Jome

+0

好吧,我最终做的是将User和Group类的id设置为ObjectId'private ObjectId id;'这似乎解决了问题。不过,我的印象是ID可以是String,int,Long等吗? Morphia没有意识到这一点? 投票这个答案反正...... :) – Jome

+0

你的发现显示_id属性作为ObjectId,但你的代码显示他们作为字符串。你的收藏中是否有混合数据?作为ID的字符串非常好。 – evanchooly