6

春のデータグラフを使用しているすべての患者開発者の皆さん、こんにちは。ドキュメントが非常に少なく、テストカバレッジがかなり不十分なため、フレームワークがどのように機能するかを理解するのが非常に難しい場合があります。現在、SDG1.1で導入された新しいフェッチングアプローチに関連するいくつかの質問があります。SDG 1.1のライトスルーとは対照的に、2.0では@Fetchアノテーションが付けられたリレーションと関連オブジェクトのみが熱心にフェッチされ、他のオブジェクトは怠惰にフェッチされることになっています..そして今私の最初の質問:

  • エンティティのロードとレイジーリレーションでのゲッターの呼び出しが同じトランザクションで行われる場合、要求されたコレクションが自動的にフェッチされるようにSDGを構成することは可能ですか?トランザクションスコープ内の永続コンテキストの種類、または機能リリースで計画されている可能性があります。
  • @RelatedToアノテーションのレイジーコレクションを一度にフェッチするにはどうすればよいですか?Neo4jOperationからのfetch()メソッドでは、1つのエンティティのみをフェッチできます。リスト全体を反復処理して、各オブジェクトのエンティティをフェッチする必要がありますか?指定されたオブジェクトがすでにフェッチ/初期化されているかどうかを確認するための最良の方法は何でしょうか?
  • 提案として、初期化されていないオブジェクトを操作するときにNPEを取得する代わりに、一種の遅延読み込み例外がスローされると、より直感的になると思います。さらに、オブジェクトが初期化されておらず、idを除くすべてのメンバープロパティがnullの場合、equalsメソッドは初期化されていないさまざまなオブジェクトにtrueを提供できるため、動作は誤解を招きます。これは、たとえばセットのアプライアンスを考えると非常に深刻な問題です。
  • SDG 2.0.0.RC1で作業しているときに気付いた別の問題は、次のとおりです。フェッチされていないコレクションに新しいオブジェクトを追加すると、適切に追加されて永続化される場合がありますが、そうでない場合もあります。このケースのテストを作成しましたが、非決定論的な方法で機能します。失敗することもあれば、成功することもあります。ユースケースは次のとおりです。

    Group groupFromDb = neoTemplate.findOne(group.getId(), Group.class);
    assertNotNull(groupFromDb);
    assertEquals("Number of members must be equals to 1", 1,    groupFromDb.getMembers().size());
    User secondMember = UserMappingTest.createUser("secondMember");
    groupFromDb.addMember(secondMember);
    neoTemplate.save(groupFromDb);
    Group groupAfterChange = neoTemplate.findOne(groupFromDb.getId(), Group.class);
    assertNotNull(groupAfterChange);
    assertEquals("Number of members must be equals to saved entity", groupFromDb.getMembers().size(), groupAfterChange.getMembers().size());
    assertEquals("Number of members must be equals to 2", 2, groupAfterChange.getMembers().size());
    

このテストは、最後のアサートで失敗する場合があります。つまり、メンバーがセットに追加される場合と追加されない場合があります。問題はManagedFieldAccessorSetのどこかにあると思いますが、これは決定論的ではないため、言うのは難しいです。mvn2とmvn3を使用してjava1.6_22と1.6_27でテストを実行すると、常に同じ結果が得られました。テストが失敗する場合もあります。Userequalsの実装は次のようになります。

@Override
public boolean equals(final Object other) {
    if ( !(other instanceof User) ) {
        return false;
    }
    User castOther = (User) other;
    if(castOther.getId() == this.getId()) {
        return true;
    } 
    return new EqualsBuilder().append(username, castOther.username).isEquals();
}

--@ Fetchで注釈が付けられたオブジェクトにはシリアル化可能なjavaHashSetが使用され、遅延ロードされたフィールドにはシリアル化不可能でシリアル化不可能な例外が発生するManagedFieldAccessorSetが使用されることも少し問題があります。

ヘルプやアドバイスは大歓迎です。前もって感謝します!

4

2 に答える 2

4

Michaelが説明するfetch()テクニックの使用方法を示す簡単なコードサンプルをまとめました。

http://springinpractice.com/2011/12/28/initializing-lazy-loaded-collections-with-spring-data-neo4j/

于 2011-12-28T08:26:12.453 に答える
3

単純なマッピング アプローチは Spring Data Neo4j 2.0 に追加されただけなので、高度な AspectJ マッピングほど成熟していません。私たちは現在、それをより広範囲に文書化することに取り組んでいます。

遅延読み込みオプションも最近追加されました。ですから、あなたのフィードバックは大歓迎です。

現在、SDN は、遅延ロードされたオブジェクトに対してプロキシ アプローチを採用していません。そのため、自動の「アクセス時のフェッチ」は (まだ) サポートされていません。そのため、ロードされていないフィールドにアクセスしても例外はスローされず、エンティティが完全にロードされていない場合は「検出」する手段がありません。

現在のスナップショットには、template.fetch()遅延ロードされたオブジェクトとコレクションを完全にロードする操作があります。

HashSet と ManagedSet の問題を検討しますが、これが適切な解決策ではないことは間違いありません。

テストケース用。getId() はLongオブジェクトまたはlongプリミティブを返しますか? オブジェクトgetId().equals(castOther.getId())の参照の等価性は保証されていないため、ここで使用するのが賢明かもしれません。Number

于 2011-11-23T19:08:22.877 に答える