在java appengine代码上获得一个奇怪的错误,以前工作正常(没有任何改变,但数据存储区中的数据)。
我正在尝试迭代查询结果并更改实体的一些属性。查询确实返回一组结果,但是,当我尝试访问列表中的第一个结果时,它会在尝试访问其任何属性(但其键)时抛出异常。这是例外:
org.datanucleus.state.JDOStateManagerImpl isLoaded: Exception thrown by StateManager.isLoaded
Could not retrieve entity of kind OnTheCan with key OnTheCan(3204258)
org.datanucleus.exceptions.NucleusObjectNotFoundException: Could not retrieve entity of kind OnTheCan with key OnTheCan(3204258)
at org.datanucleus.store.appengine.DatastoreExceptionTranslator.wrapEntityNotFoundException(DatastoreExceptionTranslator.java:60)
这是我的代码:
PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = null;
List<OnTheCan> cans;
query = pm.newQuery("SELECT this FROM " + OnTheCan.class.getName() + " WHERE open == true ORDER BY onTheCanId ASC");
query.setRange(0, num);
cans = (List<OnTheCan>) query.execute();
for (OnTheCan c : cans)
{
System.err.println(c.getOnTheCanId()); // this works fine! getting the key works
c.setOpen(false); // failure here with the above exception
c.setAutoClosed(true);
c.setEndTime(new Date(c.getStartTime().getTime() + 600000/*10*60*1000*/));
}
pm.close();
代码在尝试执行c.setOpen(false)时抛出异常 - 这是我第一次访问或设置不是密钥的属性。所以我的数据存储区中似乎有一个虚拟实体,密钥为3204258.这个实体并不存在(从管理控制台查询数据存储区)但由于某种原因它被查询返回。我的数据存储可能处于不一致状态吗?
我通过将其作为for循环的第一行来管理以下解决方法。显然是一个丑陋的黑客:
if(c.getOnTheCanId()== 3204258){ 继续; }
有什么想法吗?
答案 0 :(得分:2)
我认为您的某个索引可能已损坏。您可能需要检查http://appengine.google.com/datastore/indexes?&app_id= {your_app_id}并查看其中是否有任何报告错误。如果是这样,他们可能需要重建。
这可能会有所帮助(取自http://osdir.com/ml/GoogleAppEngine/2009-05/msg00904.html):
真空并重建索引:
答案 1 :(得分:0)
这可能是像Andrei所说的索引损坏,但如果您不愿重建所有索引,请尝试仅删除该实体。像这样:
if (c.getOnTheCanId() == 3204258) {
//continue;
pm.deletePersistent(c);
}
在没有if子句的情况下再次测试之后......
好的,还有其他一些你可以尝试的东西
检查自动索引和自定义索引(index.yaml文件)。看看你是否不再使用某些查询,但无论如何你已将其编入索引。也许这就是为什么你有错误的索引表。
查看您是否可以使用该ID查询实体。像这样:
Key k = KeyFactory.createKey(OnTheCan.class.getSimpleName(),3204258); pm.getObjectById(OnTheCan.class,k);
然后尝试将其删除。
看看你是否可以获得实体的属性,也许这是你期望的另类。