2

DB から適切な結果をスクロールして、巨大なファイル レポートを作成する必要がある場合の典型的なタスクを考えてみましょう。ORM フレームワークはHibernate. OutOfMemoryExceptionこのようなパターンを回避する方法は 3 つあります。

  1. 使用session.evict(...):

    ScrollableResults customers = session.createQuery("from Customers order by id").scroll(ScrollMode.FORWARD_ONLY);
    while (customers.next()) {
        Customer customer = (Customer) customers.get(0);
        addDataToReport(customer);
        session.evict(customer);
    }
    
  2. 使用session.clear():

    ScrollableResults customers = session.createQuery("from Customers order by id").scroll(ScrollMode.FORWARD_ONLY);
    int i = 0;
    while (customers.next()) {
        Customer customer = (Customer) customers.get(0);
        addDataToReport(customer);
        if ( ++i % 1000 == 0) session.clear();
    }
    
  3. 使用CacheMode.IGNORE:

    ScrollableResults customers = session.createQuery("from Customers order by id").setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);
    while (customers.next()) {
        Customer customer = (Customer) customers.get(0);
        addDataToReport(customer);
    }
    

したがって、問題は次のとおりです。これらの方法のうち、前述の目的に対して (パフォーマンスの意味で) 最も優れているのはどれですか? それとも、もっと効果的な方法が他にあるのでしょうか?

4

1 に答える 1

4
  • CacheMode.IGNOREあなたの問題とは何の関係もありません。セッションキャッシュではなく、第2レベルのキャッシュに関するものです。
  • evict()CascadeType.DETACHまたはなしでリレーションシップが構成されている場合、関連するエンティティは削除されませんCascadeType.ALL。だということだ:
    1. カスケード エビクションのない関連エンティティはメモリに蓄積されます
    2. カスケードされたエビクションを持つ関連エンティティは、たとえ同じであっても、反復ごとに再ロードされます
  • したがって、次のアプローチclear()が最適なオプションです。
    1. 呼び出されると、セッション キャッシュからすべてのエンティティが削除されます
    2. 関連するエンティティのセッション キャッシュを活用できるように、反復ごとに呼び出されるわけではありません。
于 2013-04-13T09:51:39.673 に答える