2

以前は正常に動作していた 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) {続行; }

何か案は?

4

2 に答える 2

2

インデックスの 1 つが破損している可能性があります。http://appengine.google.com/datastore/indexes?&app_id= {your_app_id} を確認して、エラーが報告されているアプリがないか確認してください。その場合は、再構築する必要があります。

これは役に立つかもしれません ( http://osdir.com/ml/GoogleAppEngine/2009-05/msg00904.htmlから取得):

インデックスをバキュームして再構築するには:

  1. index.yaml 仕様のバックアップを作成します。
  2. 管理コンソールから ERROR 状態のインデックスを特定します: http://appengine.google.com/datastore/indexes?&app_id= {app_id}
  3. index.yaml ファイルから ERROR のインデックスの定義を削除します。
  4. 「appcfg.pyvacuum_indexes your_app_dir/」を実行します
  5. ERROR インデックスが管理コンソールに表示されなくなるまで待ちます。
  6. index.yaml ファイルの変更されたバージョンを元のファイルに置き換えます。
  7. 「appcfg.py update_indexes your_app_dir/」を実行します
于 2010-06-22T09:39:42.817 に答える
0

Andreiが言ったように、おそらくインデックスの破損ですが、すべてのインデックスを再構築したくない場合は、そのエンティティだけを削除してみてください。このようなもの:

  if (c.getOnTheCanId() == 3204258) {
            //continue;
            pm.deletePersistent(c); 
        }

if句なしで再度テストできるようになったら...


それでは、他にも試すことができることがいくつかあります

  1. 自動インデックスとカスタムインデックス(index.yamlファイル)を確認します。クエリをもう使用しないが、とにかくインデックスを作成しているかどうかを確認します。たぶんこれがあなたが間違ったインデックステーブルを持っている理由です。

  2. そのIDでエンティティをクエリできるかどうかを確認してください。このような:

    キーk=KeyFactory.createKey(OnTheCan.class.getSimpleName()、3204258); pm.getObjectById(OnTheCan.class、k);

    その後、それを削除してみてください。

  3. エンティティのプロパティを取得できるかどうかを確認してください。おそらく、それはあなたが期待するものとは異なる種類です。

于 2010-06-22T12:19:48.890 に答える