0

例: ■ クラス A のオブジェクト a が、オブジェクト b、c、および d と関連しています。
私が行った場合:

SelectQuery query = new SelectQuery(A.class);
query.addPrefetch("b").setSemantics(PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
query.addPrefetch("c").setSemantics(PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
List<?> res = context.performQuery(query);

じゃあ後で:

SelectQuery query = new SelectQuery(A.class);
query.addPrefetch("d").setSemantics(PrefetchTreeNode.DISJOINT_PREFETCH_SEMANTICS);
List<?> res = context.performQuery(query);

a から b および c への関係は無効になります (DataRowUtils の 115 行目を参照)。

Cayenne 3.0.2 を使用していますが、動作はバージョン 3.1 と 3.2M1 で同じようです。

この問題を回避する方法はありますか?

私の考えは、この関数でクラス A の CayenneDataObject をオーバーライドすることです。

public void writePropertyDirectly(String propName, Object val) {
    if(propName.equals("b") || propName.equals("c")) {
        if(val instanceof Fault && readPropertyDirectly(propName) != null) {
            return;
        }
    }
    super.writePropertyDirectly(propName, val);
}

それは悪い考えですか?うまくいくようです。
ロードしたら、データベースから b と c をまったく更新したくありません。
ありがとう

4

1 に答える 1

0

実際、この動作は予期されたものです。対 1 リレーションシップの無効化は、select で熱心に行われ、それらの新しいビューを保証し、必要に応じてメモリ キャッシュから簡単に復元できることを前提としています。したがって、'getB' または 'getC' を呼び出したときの単純な FK リレーションシップの場合、Fault のオブジェクトが取得され、DB クエリは表示されません。

その例外 (to-one を読み取るときの予期しないクエリ) は、いくつかの理由で発生する可能性があります。最も可能性が高いのは、ObjectContext ローカル キャッシュの熱心なガベージ コレクションです。これを防ぐために、Cayenne 3.1 および 3.2では、 「cayenne.server.object_retain_strategy」プロパティとして保持戦略セットを指定する機能が提供されています。「ハード」戦略を試して、違いがあるかどうかを確認できます。

上記のソリューションは、 A にアクセスして更新するすべてのシナリオを知っている場合にのみ問題ありません。一般に、データの更新でデバッグが困難な問題が発生する可能性があります。

于 2014-09-30T18:17:43.223 に答える