2014-01-28 25 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