2

次のエンティティのセットがある場合:

A --> (unowned) B
  \
   --> (owned) List<C>

D --> (owned) List<E> --> (owned) List<F> --> (unowned) A
  \
   --> (unowned) H

G --> (unowned) H
  \
   --> (unowned) D
  \
   --> (unowned) B
  \
   --> (unowned) A
  \
   --> (unowned) F
  \
   --> (unowned) F

トランザクションでこれらすべてのオブジェクトに触れている場合、4 つのエンティティ グループ (A、B、D、H) を数えます。これは許可する必要があります (ドキュメントによると、最大 5 つまで持つことができます)。

2 つの質問: 1) それらをどのように取得/作成するかは重要ですか? つまり

C c = new C(a);
a.getCs().add(c);

親子関係にもかかわらず、どういうわけか2つの別々のエンティティグループを使用していますか? それとも、G が F の 2 つの異なる値を持っているという事実 - それは 2 つのエンティティ グループですか、それとも 1 つですか?

2) オブジェクトにアクセスすると、どのくらい深くなりますか? つまり、私も持っている場合

D --> (owned) List<K> --> (owned) List<L> --> (unowned) M

K、L、または M にアクセスしていなくても、appengine はトランザクションでアクセスされるエンティティ グループのリストに M を含めますか?

私は概念的な観点から自分のオブジェクト モデルにかなり満足しています (appengine がなければ、同じようにもう一度設計するだろうと確信しています)。すべての親?

あるいは、これがデータベースの世界では些細なことだとすると、DataStore for Cloud SQL を 6 か月でやめた人はどれくらいいるでしょうか? (おそらく、最後はスタックオーバーフローにとって主観的すぎるかもしれませんが、それは本物の質問です)

アップデート

すべてをデバッグするために生成されたログを調べた後、ある時点で次の行が表示されることがわかります。

24634 [1419746043@qtp-647750325-2] DEBUG DataNucleus.Persistence - Performing reachability algorithm on object with id "com.google.appengine.api.datastore.Key:D("alex@hotmail.com")"

その後、そのルート エンティティからアクセスできるすべてのオブジェクトを大量に取得します。これには、所有されていない (つまり、アクセスされたエンティティを親として使用していない) エンティティが多数含まれているため、これがトランザクションの失敗の原因であると推測し、Q2 への回答は「どこにでも'

だから... Q3 - どうすればこの動作を防ぐことができますか? 変更された F の 2 つのインスタンスを永続化するために、makePersistent(D) を呼び出していることに注意してください。

4

2 に答える 2

3

いくつかの注意:

  1. すべての高レベルのデータストアAPI(JDA / JPA / Objectify)は、低レベルのAPIに基づいて構築されています。低レベルのAPIよりも「多く」を実行することはできません。データストアを理解したい場合は、低レベルAPIを理解する必要があります。

  2. エンティティ間の関係は、あるエンティティが別のエンティティのキ​​ーを持つプロパティを持っていることに基づいています。簡単に言うと、エンティティには別のエンティティのIDが含まれています。

  3. エンティティからキープロパティを削除するだけで、エンティティの関係を壊すことができます。SQLの世界で使用されるような参照整合性はありません。制約なしで、関係のどちらの側でもエンティティを削除できます。

  4. エンティティグループは祖先関係に基づいており、上記のポイント2のエンティティ関係とは何の関係もありません。祖先関係はキーに基づいています。子キーにはすべての親キーのキーが含まれます。

  5. 祖先関係はキーに基づいているため、エンティティが作成されたときにのみ確立できます。キーは不変であるため、後で変更することはできません。

  6. エンティティグループには、1書き込み/秒の書き込み/更新制限があります。したがって、すべてのエンティティを1つの共通のGenericObjectの下に置くことは、実際には悪い考えです。エンティティグループはパフォーマンスに影響するため、エンティティグループの設計方法には十分注意する必要があります。出発点として、各ユーザーエンティティをエンティティグループのルートとして配置することをお勧めします。

  7. エンティティグループはトランザクションスコープを定義するように設計されており(基本的には、これらのエンティティが同じサーバー上に存在するため、書き込み制限があります)、エンティティ間の論理的な関係を構築するためにそれらを使用しないでください。

于 2012-09-20T06:17:01.523 に答える
2

jdoconfig.xml に以下を追加することで問題を解決できました。

<property name="datanucleus.persistenceByReachabilityAtCommit" value="false"/>

これは、http://www.datanucleus.org/products/datanucleus/performance_tuning.htmlで文書化されています。

なぜこれが必要なのか、あるいはなぜ私のオブジェクト モデルが間違っているのかについて誰かコメントを残したい場合は、JDO と appengine を初めて使用するので、非常に感謝しています。

于 2012-09-22T02:29:22.090 に答える