- PR -

JPA+HibernateでJDBCバッチ更新

1
投稿者投稿内容
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2006-12-27 11:57
Java SE 6からSEで使えるようになったJava Persistent API。
裏をHibernateにして使ってみようかと考えているのですが、使い始める前に一点確認したいことがあるので、もし知っている方がいれば教えてください。

対象アプリケーションは、1トランザクションで大量のINSERTが発生します。
今まではJDBCを生で使用しており、INSERT性能を上げるためにPreparedStatement.addBatch()/executeBatch()によるバッチ更新を使っていました。

JPA+Hibernateでも、大量INSERTにこの手法は使えるのでしょうか?

ちょっと調べた感じでは、HibernateはコミットやSession.flush()によりセッションがフラッシュされるまで複数のINSERTを貯めておき、フラッシュ時にはプロパティ"hibernate.jdbc.batch_size"の単位でバッチINSERTを行うっぽいですが、この理解は正しいですか?

正しいとして、これはJPA経由でHibernateを使ったときも同様ですよね? フラッシュのためのAPIはEntityManager.flush()とかになるかもしれませんが。

急ぎではないので、時間ができたらソースを追うか、実験してみますが、もしご存知の方がいれば教えていただけると助かります。
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2006-12-27 14:07
ところで、JPAが結局Java SE 6からドロップされた、なんて話はあります?
rt.jarにjavax.persistenceないし、リリースノート見ても特に書いてないんですが。
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2006-12-28 11:34
ご参考になるかどうかわかりませんが。

引用:

カーニーさんの書き込み (2006-12-27 11:57) より:

ちょっと調べた感じでは、HibernateはコミットやSession.flush()によりセッションがフラッシュされるまで複数のINSERTを貯めておき、フラッシュ時にはプロパティ"hibernate.jdbc.batch_size"の単位でバッチINSERTを行うっぽいですが、この理解は正しいですか?



Session.save(Object obj) や Session.saveOrUpdate(Object obj) のリクエストはプールされていて、Session.flush() 時にまとめて INSERT が実行されるところまでは、私の経験とカーニーさんのご理解が一致しています。
これが単純な INSERT の羅列によるのか、バッチ INSERT で実行されているのかまでは調査していません(_ _)
(今関わっているプロジェクトで Hibernate を利用しており、その設定を見ると hibernate.jdbc.batch_size は未設定(デフォルト値)でした。)

本家のドキュメントによると「A non-zero value enables use of JDBC2 batch updates by Hibernate.」だそうなので(すでに調査済みと思われますが)、ご所望の要件に使うのには問題ないように見えます。

もう一つ、javax.persistence の件では、これをキーワードに検索してみると Java SE 6 SDK ではなく Java EE 5 SDK にあるようです。
(ご参考:http://java.sun.com/javaee/5/docs/api/javax/persistence/package-summary.html

[ メッセージ編集済み 編集者: Gio 編集日時 2006-12-28 11:37 ]

[ メッセージ編集済み 編集者: Gio 編集日時 2006-12-28 11:38 ]
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2006-12-28 16:17
Gioさん、ご返答どうもありがとうございます。

引用:

Gioさんの書き込み (2006-12-28 11:34) より:
本家のドキュメントによると「A non-zero value enables use of JDBC2 batch updates by Hibernate.」だそうなので(すでに調査済みと思われますが)、ご所望の要件に使うのには問題ないように見えます。



あの後、軽くHibernate Core & Hibernate Entirty Managerのソースを眺めて見ましたが(動かしてはいない)、大きな読み違いをしていなければ、たぶんaddBatch()/executeBatch()をやってくれるっぽいです。

引用:

もう一つ、javax.persistence の件では、これをキーワードに検索してみると Java SE 6 SDK ではなく Java EE 5 SDK にあるようです。
(ご参考:http://java.sun.com/javaee/5/docs/api/javax/persistence/package-summary.html



こういう記事もありまして・・・。
http://www.atmarkit.co.jp/fjava/column/koyama/koyama03.html

SDK付属のAPIリファレンスにもjavax.persistenceは入ってなかったっす・・・。
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2007-02-01 20:46
ちょっと時間が経ってしまいましたが、実際に動作させたところ、期待通りの動作をしてくれることが確認できました。DBにOracleを用意し、Oracle側でSQLトレースを取ったところ、以下の通り、1回のINSERT実行(Executeのcount)で複数行(今回は2行=Executeのrows)がInsertされます。

コード:
********************************************************************************
insert into dept (dname, location, deptno)
values
 (:1, :2, :3)

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          1          0           0
Execute      1      0.00       0.02          0          1         10           2
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.00       0.03          0          2         10           2
********************************************************************************



# 実際にバッチINSERTが効果的かどうかはデータベース種別や、JDBCドライバに依存しますが。

ちなみに、TopLink JPAも検討しています。
こっちも同じようなことが気になりましたので、調査中です。興味のある方はこちらまでどうぞ。
http://otn.oracle.co.jp/forum/thread.jspa?threadID=35000085&tstart=0
1

スキルアップ/キャリアアップ(JOB@IT)