2011-07-15 15 views
0

eclipselink JPAを使用してエンティティを取得しようとしていますが、単一のエンティティを取得するために実行されるクエリの数を減らす方法を探しています。メインエンティティと同じクエリ内のサブエンティティを取得するには、@ JoinFetchアノテーションを使用する必要があると思います。これは、単一レベルの結合ではうまく動作しますが、複数のレベルではうまく動作しません。単一のクエリでネストされたJPAエンティティを取得する方法

以下の例では、EntityAにはEntityCのコレクションが含まれています。 EntityAを取得すると、3つのエンティティデータすべてを返す単一のクエリが必要です。実際には、EntityAとEntityBを結合して2つのクエリを生成し、EntityBとEntityCを結合する別のクエリを生成します。

これを1つのクエリに組み合わせることはできますか?

class EntityA { 
    @OneToMany(mappedBy = "entityALink", fetch = FetchType.EAGER) 
    @JoinFetch 
    private Collection<EntityB> entityBs; 
} 

class EntityB { 
    @JoinColumn(name = "X", referencedColumnName = "Y") 
    @ManyToOne(optional = false, fetch = FetchType.EAGER) 
    private EntityA entityALink; 

    @JoinColumn(name = "A", referencedColumnName = "B") 
    @ManyToOne(optional = false, fetch = FetchType.EAGER) 
    @JoinFetch 
    private EntityC entityCLink; 
} 

class EntityC { 

    @Id 
    @Basic(optional = false) 
    @Column(name = "SomeColumn") 
    private String someField 
} 

答えて

0

あなたは、クエリの数を減らす必要がある場合は、遅延初期化を使用して - ではなくFetchType.EAGERのFetchType.LAZY - 必要このようにJPAは、データベースからデータを取得します。しかし、エンティティがマネージャから切断されているときは、これは機能していないことを覚えておく必要があります。したがって、このエンティティを他のサーバに送信してフォームをシリアル化する場合(マルチレベルアプリケーションなど)、このエンティティをマネージャに再度接続する必要があります。 1つのサーバーでアプリケーションを実行すると、この問題は発生しません。

あなたの質問に正確に答えているわけではありませんが、このコードを最適化するのに役立ちます。

正確な答え質問: 名前付きのクエリを使用している可能性がありますが、クエリはSQLのネイティブクエリに対して解析されています。しかし、ネイティブクエリメソッドを使用している可能性がありますか?あなたは結果のエンティティクラスを設定するには、注釈を@SqlResultSetMappingについてお読みください。このpurpuseのために

em.createNativeQuery("SELECT ... your queries") 

...ここ

+0

私の主な目標は、できるだけ速いタイムでアプリケーションの起動時に、非常に大きなデータセットをロードすることです後でデータベースに戻ってくる必要はありません。怠惰なフェッチは、データが必要になるまで問題を解決するだけです。これまでのアプローチでは、エンティティアノテーションを使用して結合を指定する方法がありましたが、名前付きクエリがより良いソリューションを提供するかどうかは不思議です。 – insano10

+0

ネイティブクエリを使用したくない場合は、データベースビューを使用し、AフィールドとBフィールドを持つ他のエンティティを作成する方が良いでしょうか?しかし、これは多対1多重度の問題を解決するものではありません。ただし、あなたのケースでは単一のビューに簡略化することができますか? – wojand

+0

提案していただきありがとうございます。最後に、クエリと遅延フェッチを使用してこの問題を解決しました。 JPAが私が望むすべてのデータを返すことを期待するのではなく(遅すぎた)、私はDAOが2つの別のクエリを呼び出し、データを一緒にスティッチすることを選択しました。エンティティ間のリンクは、熱心ではなく怠惰です。どのくらいのデータが戻ってくるかを判断するのはクエリまでです。私はeclipselinkを使用しているので、テーブル間の結合を最適化するためのクエリヒントを指定することができました。 – insano10