GAE数据存储区查询整数字段

时间:2012-12-12 19:11:51

标签: java google-app-engine google-cloud-datastore apache-commons-beanutils

在查询GAE数据存储区时,我注意到了奇怪的行为。在某些情况下,Filter不适用于整数字段。以下java代码重现了该问题:

log.info("start experiment");

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

int val = 777;

// create and store the first entity.
Entity testEntity1 = new Entity(KeyFactory.createKey("Test", "entity1"));
Object value = new Integer(val);
testEntity1.setProperty("field", value);
datastore.put(testEntity1);

// create the second entity by using BeanUtils.
Test test2 = new Test(); // just a regular bean with an int field
test2.setField(val);

Entity testEntity2 = new Entity(KeyFactory.createKey("Test", "entity2"));

Map<String, Object> description = BeanUtilsBean.getInstance().describe(test2);
for(Entry<String,Object> entry:description.entrySet()){
    testEntity2.setProperty(entry.getKey(), entry.getValue());
}

datastore.put(testEntity2);


// now try to retrieve the entities from the database...

Filter equalFilter = new FilterPredicate("field", FilterOperator.EQUAL, val);

Query q = new Query("Test").setFilter(equalFilter);

Iterator<Entity> iter = datastore.prepare(q).asIterator();

while (iter.hasNext()) {
    log.info("found entity: " + iter.next().getKey());
}

log.info("experiment finished");

日志如下所示:

INFO: start experiment
INFO: found entity: Test("entity1")
INFO: experiment finished

出于某种原因,它只找到第一个实体,即使这两个实体实际上都存储在数据存储区中,而且两个实体都存储在“#”字段中。值是777(我在数据存储区查看器中看到它)!为什么实体的创建方式很重要?我想使用BeanUtils,因为它很方便。

本地devserver和部署到GAE时会出现同样的问题。

3 个答案:

答案 0 :(得分:2)

好的,我发现了发生了什么。 “问题”是由于某种原因,BeanUtils将整数转换为字符串。字符串在数据存储区查看器中看起来完全相同,但它当然不一样。这几乎让我上当了。我应该研究apache BeanUtils手册或其他东西。

答案 1 :(得分:0)

在查询数据之前,您是否在写入后1秒钟给出了数据存储区?有时您不必(可能是祖先的查询),但有时您也这样做。 GAE / J文档将提供完整的详细信息。

答案 2 :(得分:0)

使用BeanUtils创建实体这一事实完全无关紧要。如果实体位于数据存储区中(您可以在查看器中看到它们)并且字段值已编制索引(它不会在数据存储区查看器中的值旁边显示“未编制索引”),则可以使用过滤器查询它们。这有效......它是数据存储区的基本功能。

鉴于实体已创建并编入索引,我建议Ian Marshalls建议可能是正确的。要对此进行测试,请转到App Engine的首选项,然后取消选中“启用本地HRD支持”。这将确保您在编写实体时可以立即查询它。

如果你存储一个Integer或int或任何其他数值并不重要 - 它们都在内部存储为long值,当你读回你的值时,你会得到一个Long(尽管存储一个整数)