-1

Hibernate の名前付きクエリを使用して、非常に大きなデータセット (200 万行以上) を返すストアド プロシージャを実行しています。DB は Oracle 11g です。

例えば: Query query = session.getNamedQuery(procName);

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

100,000 行のような小さなデータセットでは、すべて問題ありません。ただし、1,000,000 でテストするとすぐに OutOfMemory エラーが発生します。

query オブジェクトから、listIterator を取得します。データは 1 回だけフェッチされたと仮定し、listiterator ( query.list().listIterator())を反復処理します。

第 2 レベルのキャッシュが構成されていません。これらの設定は、Oracle ストアド プロシージャを扱うときに役立ちますか。

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

基本的に、Hibernate でストアド プロシージャを使用して大規模なデータセットの取得を管理するにはどうすればよいですか。

百万の感謝

4

2 に答える 2

1

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

于 2011-08-14T02:19:46.020 に答える
0

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

于 2011-08-14T04:30:29.700 に答える