2011-08-14 15 views
-1
私はDBは、インスタンスのOracle 11gの

HibernateがOutOfMemoryを

(2万行の上に)非常に大きなデータセットを返すストアドプロシージャを実行するために、Hibernateの名前付きクエリを使用しています

につながります私は、休止状態のドキュメントから、 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.htmlに記載されているように、setFirstResult/setMaxResultを使用することはできません。

すべてがうまくいけば、100,000行のような小さなデータセットです。しかし、私が1,000,000でテストするとすぐに、私はOutOfMemoryエラーを受け取ります。

クエリオブジェクトから、私はlistIteratorを取得します。データが1回だけ取り出されたと仮定して、リストアテイター(query.list().listIterator())を繰り返しました。

第2レベルのキャッシュが設定されていません。 これらの設定は、Oracleストアド・プロシージャを処理する場合に役立ちますか。

query.setCacheMode(org.hibernate.CacheMode.IGNORE); query.setFetchSize(1000);
query.scroll(org.hibernate.ScrollMode.FORWARD_ONLY);

基本的に、どのように私は、Hibernateに保存されprocsのを使用して大規模なデータセットの取得を管理します。

百万の感謝

+0

なぜ200万行を返そうとしていますか?バッチ処理をお勧めします。 –

答えて

1

それはあなたのクエリから返されたデータを処理する方法に完全に依存。これを典型的なクエリとして扱う場合、つまり、その上でlist()を呼び出し、その結果をCollectionに格納すると、その多くの行でメモリ制限を破棄します。キーは、バッチでそれらを取得して処理することです。私は、Hibernateでこれを行う典型的な方法は、結果がScrollableResultsであり、セッションが第1レベルのキャッシュとして動作し、ロードされているすべてのオブジェクトを格納するので、セッションを定期的にflush()clear()に覚えていると思います。 Hibernateでのバッチ処理の説明を見てください。ただし、Hibernateのbatch fetchingおよび関連する概念と混同しないよう注意してください。彼らは2つの異なる動物です。

0

あなたの問題は、メモリ使用量よりもHibernateのほうが少ないです。私は、JMSメッセージが少量のデータでうまく動作していたのと同様の状況を抱えていました。その後、すべてがより多く爆発しました。一度にすべての2mmレコードが必要になるのではないかと思うので、データセット全体だけではなく、データのスライスを返すことができるように、ストアドプロシージャを更新してオフセットを取得できるかどうかを確認してください。