2017-08-11 9 views
0

遅延コレクション

class Order{ 
    int id; 
    String description; 
    //one to one eager load with join column specified 
    Detail details; 
    //one to many lazy load with mapped by specified 
    Collection<Item> items; 
} 

class Detail{ 
} 

class Item{ 
    String name; 
    //reference to order 
} 

簡単なエンティティモデル、次の点を考慮それでは、要件がいくつかの基準によりアイテムの詳細ですべての注文をロードすることであるとしましょう(例:説明と一致するもの)。シンプルな、私は "どこから説明するのか..."のようなhqlを書く。たとえば、1000個のエンティティがロードされ、アイテムのコレクションが遅延ロードされます。私はサイズを呼び出すことによってセッション内で強制的にロードします。私はアイテムのためのバッチフェッチを使用することにしましたので、当然の

これはN + 1つの問題につながりました。バッチサイズの注釈をアイテムコレクションに追加し、予想よりもはるかに少ないクエリを追加しました。

しかし、私はすべての「詳細」に興味を持っていないですが、それは1つの熱心な負荷に1であるため、常にこれをロードするためにつき1つのクエリがあります。私は単にこれらのクエリを取り除きたいだけです。

これを解決するために、私は細かいことなく選択をしようとしますが、アイテム(コレクション)をクエリに含める方法がわからないので、すべてを選択した場合とまったく同じ方法でロードされます遅延ロードされ、その後の呼び出しでバッチサイズを利用することができます)。いくつかの提案は、where句でjoinを使うことですが、空の配列リスト(Lazyローディングの場合のようにPersistentBagではなく)でコレクションを初期化します。

解決策をお探しですか?

+0

'Detail'を遅延ロードしないのはなぜですか? – ujulu

+0

デフォルト(熱心な)読み込みに依存するアプリケーションの他の部分があります。さらに、1-1を遅延ロードにするためのすべてのソリューションは(バイトコードの計測など)簡単であり、既存のコードを壊すリスクを冒したくありません。 – smi

答えて

0

一つの可能​​な解決策は次のとおりです。

  • は、クエリの結果が含まれますPOJOを作成します。例:だからあなたはあなたが興味のある情報だけを含むOrderResultのインスタンスのリストを取得します

    List<OrderResult> resultList = entityManager.createQuery("SELECT NEW OrderResult(o.description, i.name) FROM Order o JOIN o.items i where <condition>", OrderResult.class).getResultList(); 
    

public class OrderResult { 
    private String description; 
    private String itemName; 
    // ... more fields, if any 

    public OrderResult(String desc, String itemName) { 
     this.description = desc; 
     this.itemName = itemName; 
    } 

    // getters & setters 
} 
  • としてコンストラクタ式を使用して、JPQLクエリを作成します。 。

    注1:あなたはHQLの話をしているが、HQLはHibernate固有のレガシークエリ言語です。 HibernateはJPAの実装であり、あなたの質問にJPAを付けたので、この解決法もあなたの環境で動作するはずです。

    注2:ソリューションでは、私は、select句でNEWを使用して定義されるJPQLのいわゆるコンストラクタ式を使用しています。

    SELECT NEW com.mycompany.myproject.order.OrderResult(...) FROM ... 
    

    注3:これはあなたを与えることですNEWオペレータへの引数は、パッケージcom.mycompany.myproject.orderOrderResultクラスを置く場合、その式は次のようになります、例えば、完全修飾クラス名でなければなりませんどのようにソリューションを実装するのヒントとpseodoコードとして考える必要があります。

  • +0

    しかしあなたのソリューションは、アイテムコレクションを考慮から除外します。注文の詳細にアイテムが必要です。私が理解している限り、コンストラクタの引数にコレクションを含めることはできません。または私は何かを逃していますか? – smi

    関連する問題