2012-02-28 9 views
1

DTOオブジェクトの使用時にN + 1 SELECTSを実行している場所で休止状態に問題があります。例えばDTOオブジェクトを使用したHibernate N + 1の選択

、このJPQLクエリ:

MyDtoのコンストラクタのようなものである
SELECT com.acme.MyDto(t) FROM Thing t 

SELECT t.id FROM thing t WHERE condition 

:ような何かのクエリで結果

public MyDto(Thing t) { 
    ... 
} 

各行のすべての単一のクエリが続きます。つまり、

SELECT t.id, t.column1, t.column2 FROM thing t WHERE t.id = 1 
SELECT t.id, t.column1, t.column2 FROM thing t WHERE t.id = 2 
SELECT t.id, t.column1, t.column2 FROM thing t WHERE t.id = 3 
... 

コンストラクタはつまり、あなたが期待するように動作を休止、その後、エンティティを受け入れるが、その代わりに、個々の列いない場合は:

public MyDto(Integer id, String column1, String column2) { 
    ... 
} 

その後、生成されたSQLは次のようになります。

SELECT t.id, t.column1, t.column2 FROM thing t WHERE condition 

すべての列を取るDTOコンストラクタを作成するのとは別に、最初からすべての列を一度に選択するために休止状態を同軸化する方法はありますか?

私たちが扱っているテーブルには、100個以上の列が埋め込み可能なものにまたがっているので、巨大なコンストラクタを維持するのはかなり面倒です。テーブルは大きく正規化されており、結合はありません。

答えて

1

質問を最初に間違って読んでください... DTOを使用しているのは、特定の列だけでなくエンティティ全体を取り上げたものではないので、Hibernateがそのように動作する理由はわかりません。 DTOコンストラクタのパラメータとして全体のエンティティ。とにかく、あなただけのクエリを経由して実際のThingsをgettinのことで、それを回避することができ、その後、ループ内での線に沿って何かのDTOを構築する:それはかなりではない

public List<ThingDTO> getThingDTOs(...) 
{ 
    Query query = em().createQuery("FROM Thing t WHERE ..."); 
    query.setParameter(...); 

    List<Thing> things = query.getResultList(); 

    List<ThingDTO> thingDTOs = new ArrayList(things.size()); 
    for(Thing t : things) 
    { 
     thingDTOs.add(new ThingDTO(t)); 
    } 

    return thingDTOs 
} 

を、しかし、この方法でHibernateがフェッチすべきですすべての必要な行を1つにする

+0

これはありがとう、それは仕事をします。 –

関連する問題