Java Appengine数据存储虚拟实体-状态不一致?

Java Appengine数据存储虚拟实体-状态不一致?,java,google-app-engine,google-cloud-datastore,datanucleus,Java,Google App Engine,Google Cloud Datastore,Datanucleus,在java appengine代码上出现一个奇怪的错误,该代码过去工作正常,除了数据存储中的数据外,没有任何更改 我试图迭代查询结果并更改实体的一些属性。该查询确实返回一组结果,但是,当我尝试访问列表中的第一个结果时,它在尝试访问其任何属性但不访问其键时抛出异常。例外情况如下: org.datanucleus.state.JDOStateManagerImpl isLoaded: Exception thrown by StateManager.isLoaded Could not retrie

在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.setOpenfalse时抛出异常-这是我第一次访问或设置不是键的属性。因此,我的数据存储中似乎有一个虚拟实体,其密钥为3204258。从管理控制台查询数据存储时,该实体实际上并不存在,但由于某些原因,它将由查询返回。我的数据存储是否可能处于不一致的状态

我通过将其作为for循环的第一行来管理以下解决方法。显然是一个丑陋的黑客:

如果c.GetOnTecanid==3204258{ 持续 }


有什么想法吗?

我想你的一个索引可能已经损坏了。您可能需要检查{your_app_id},看看是否有人报告错误。如果是这样,它们可能需要重建

这可以从以下方面获得帮助:

要抽真空并重建索引,请执行以下操作:

创建index.yaml规范的备份。 从管理控制台确定状态错误中的索引:{app_id} 从index.yaml文件中删除错误索引的定义。 运行appcfg.py vacuum\u索引您的app\u目录/ 请等待,直到错误索引不再出现在您的管理控制台中。 将index.yaml文件的修改版本替换为原始版本。 运行appcfg.py update\u索引您的\u app\u dir/
正如Andrei所说,这可能是索引损坏,但如果您不愿意重建所有索引,请尝试仅删除该实体。大概是这样的:

  if (c.getOnTheCanId() == 3204258) {
            //continue;
            pm.deletePersistent(c); 
        }
在您可以在不使用if子句的情况下再次测试它之后

好的,那么,还有一些其他的事情你可以尝试

检查index.yaml文件中的自动索引和自定义索引。看看是否不再使用某些查询,但仍然对其进行了索引。也许这就是为什么索引表是错误的

查看是否可以使用该id查询实体。如下所示:

Key k=KeyFactory.createKeyOnTecan.class.getSimpleName,3204258; pm.getObjectByIdOnTheCan.class,k

然后尝试移除它

看看你是否能得到实体的属性,也许它是你所期望的另一种


您是否尝试过使用数据存储查看器获取并检查它?是-从数据存储查看器查询不会返回任何结果尝试按键获取它,由于您知道密钥。在数据存储查看器中尝试了此查询,但未返回任何结果:SELECT*FROM OnTecan,其中id=3204258如果我尝试删除您提到的实体,则会出现相同的错误:com.poo.pooserver.tasks.closeOpenOnTecask closeOnTecans:javax.jdo.JDOObjectNotFoundException:无法在Ecan上检索类型的实体使用ECAN3204258上的键NestedThrowables:org.datanucleus.exceptions.NucleusObjectNotFoundException:无法使用ECAN3204258上的键检索ECAN上类型的实体如何尝试插入具有该id的实体,然后再次尝试删除它,这可能会再次将索引与实际值同步。另外,您是使用自定义索引进行此查询,还是依赖于内置索引?