1

両方のエンティティのタイプが PersistentLogin の場合、以下の例外が発生するのはなぜですか? 同じエンティティ グループに属しているということだと思いましたが、それは間違った仮定だと思います。これを修正する方法はありますか?

これはコードです:

// the class is marked with @Transactional
@Override
public final void removeUserTokens(final String username) {
    final Query query = entityManager.createQuery(
        "SELECT p FROM PersistentLogin p WHERE username = :username");
    query.setParameter("username", username);

    for (Object token : query.getResultList()) {
        entityManager.remove(token);
    }
}

これは例外です:

Caused by: javax.persistence.PersistenceException: Illegal argument
    at org.datanucleus.jpa.NucleusJPAHelper.getJPAExceptionForNucleusException(NucleusJPAHelper.java:260)
    at org.datanucleus.jpa.EntityTransactionImpl.commit(EntityTransactionImpl.java:122)
    at org.datanucleus.store.appengine.jpa.DatastoreEntityTransactionImpl.commit(DatastoreEntityTransactionImpl.java:50)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
    ... 42 more
Caused by: java.lang.IllegalArgumentException: can't operate on multiple entity groups in a single transaction. found both Element {
  type: "PersistentLogin"
  name: "1WfCYx8bmwUGkjzP2PpmFA=="
}
 and Element {
  type: "PersistentLogin"
  name: "SfI0P8RVBjTvu0WHMSuaVA=="
}
4

2 に答える 2

5

同じエンティティ グループとは、エンティティに共通の親エンティティがあることを意味します。

2 つの最上位エンティティが同じエンティティ グループに属することはありません。

これを修正する方法はありますか?

最も簡単な方法は、トランザクション要件を緩和することです。あなたの場合、PersistentLogin エンティティを 1 つずつ削除することを意味します (ベスト エフォート ループ、できる限り削除し、エラーを再試行し、原子性の保証はありません)。

同じユーザーの PersistentLogin を同じエンティティ グループに配置したい場合は、データ モデルにかなり大きな変更を加える必要があり、全体的なパフォーマンスへの影響は不確実です。

非リレーショナル データベースでは、データ ストアのトランザクションに依存せずにアプリケーションをコーディングする必要があります。彼らは、私たちが慣れ親しんだ範囲で彼らをサポートしていません。

于 2010-02-24T05:16:47.553 に答える
1

最初に、次のドキュメント、特に「グループ間トランザクションの使用」セクションを注意深くお読み ください http://code.google.com/appengine/docs/java/datastore/transactions.html

グループ間トランザクションとは何かに関する情報: http://code.google.com/appengine/docs/java/datastore/overview.html#Cross_Group_Transactions

注: 最大 5 つの異なるグループに対してトランザクションを実行できます。

本番用の appengineでは、appengine ダッシュボードで「高レプリケーション データストア」を有効にし、ソース コード、jdoconfig.xml、または persistence.xml で「グループ間 (XG) トランザクション」を有効にする必要があります。

開発用 appengine サーバーでは、高レプリケーション データストアをシミュレートする必要があります。これについてはここで説明します

注: appengine dev サーバーのコマンドラインを起動する場合は、忘れずに高レプリケーション データストア オプションを追加してください。

~/appengine-java-sdk-1.6.2.1/bin/dev_appserver.sh
    --jvm_flag=-Ddatastore.default_high_rep_job_policy_unapplied_job_pct=20
    --address=0.0.0.0 --port=8888 --disable_update_check .

Rogerthat プラットフォームを開発している間、これにしばらく苦労しました(コードは本番環境と Eclipse では機能しましたが、コマンドラインで dev_appserver.sh を実行すると機能しませんでした)。共有する価値があると考えました。

于 2012-02-21T11:42:37.153 に答える