无法使用数据存储删除对象,在dao上查询(带有`id`)并且ds返回零结果

时间:2013-07-04 04:16:04

标签: java mongodb morphia mongodb-java

我正在尝试从数据存储中删除一个对象,但它没有删除它。代码如下:

MoIADocument moIADoc = new MoIADocument();
// update fields in moIADoc object
ds.save(moIADoc);

printDBDocs();

// create a query to retrieve objects
QueryResults<MoIADocument> foundResults = dao.find(query);
List<MoIADocument> list = foundResults.asList();

for (MoIADocument obj : list) {
    ds.delete(obj);
    MoDBIATopic topicBO = obj.getData().get(EnumChannelType.FACEBOOK).getData().get(GraphConstants.Topic_Default);
    topicBO.setInfluence(topicBO.getInfluence() * 25);
    ds.save(obj);
}
printDBDocs();

########################### 第一次打印(采用JSON格式)的结果是:

first print result

########################### for循环中的obj是:

obj in for loop

########################### 在for循环之后,print语句给出了两个对象:

last print result

为什么不通过mongoConstants.ds.delete(obj);删除旧对象?我已注释id字段广告@Id,但仍然使用相同的id保存了两个对象。这怎么可能?如果id相同,我们如何强制覆盖对象?

@Id
@Indexed
private String id;

注意:id是JSON中指示的顶级id

我尝试使用查询:

Query<MoIADocument> query1 = ds.createQuery(MoIADocument.class).disableValidation();
query1.field("id").equal(obj.getId());
ds.delete(query1);

这也没有按预期工作。

EDIT:

问题在查询结果中看起来像。使用上面的query1,它返回零结果。

2 个答案:

答案 0 :(得分:0)

我尝试了多种方法,但没有按预期工作。尝试了以下方法:

方法#1:

Query<MoDBIADocument> query1 = dao.createQuery(MoDBIADocument.class).disableValidation();
query1.field("id").equal(moDoc.getId());
QueryResults<MoDBIADocument> foundResults1 = dao.find(query1);
printDBDocs(foundResults1);

方法#2 :(使用_id代替id

Query<MoDBIADocument> query1 = dao.createQuery(MoDBIADocument.class).disableValidation();
query1.field("_id").equal(moDoc.getId());
QueryResults<MoDBIADocument> foundResults1 = dao.find(query1);
printDBDocs(foundResults1);

方法#3:

using `ds` instead of `dao` in `Approach# 1` and `Approach# 2`

方法#4:

DBObject dbObj = new BasicDBObject("id", moDoc.getId());
DBCursor cursor = COLLECTION.find(dbObj);

上述方法都没有奏效。我认为问题在于使用顶级id字段(不知何故?)..

使用内部ID(FACEBOOK)按预期工作

query1.field("data.FACEBOOK.id").equal(str);

答案 1 :(得分:0)

问题是使用String id作为@Id字段。实际上它应该是ObjectId id。这个改变类变为如下:

@Entity("Collection_IAGlobals")
public class MoDBIADocument {
    @Id
    @Indexed
    private ObjectId id;
    // some more fields
}

并更新为:

QueryResults<MoIADocument> foundResults = dao.find(query);
List<MoIADocument> list = foundResults.asList();
for (MoIADocument obj : list) {
    //do modifications in obj
    dao.save(obj);
}

这种方式不需要delete旧对象。它用新的对象替换旧对象(因为它们具有相同的id)。

使用dsdao工作正常。

但是现在,设置id字段的新问题。如果我使用一些字符串设置为:

moIADoc.setId(new ObjectId("123456"));

导致以下错误:

Exception in thread "main" java.lang.IllegalArgumentException: invalid ObjectId [123456]
    at org.bson.types.ObjectId.<init>(ObjectId.java:128)
    at org.bson.types.ObjectId.<init>(ObjectId.java:122)

任何其他方法都可以正常工作,例如:

// don't set id field
//OR
//set using default constructor of ObjectId
moIADoc.setId(new ObjectId());
//OR use other constructors e.g.
moIADoc.setId(new ObjectId(new Date(), 123456));

那么,问题是为什么ObjectId没有采用String参数?