JPA/EJB3 フレームワークは、バッチ挿入操作を行う標準的な方法を提供していますか? 永続化フレームワークに hibernate を使用しているため、Hibernate Session にフォールバックし、session.save()/session.flush() の組み合わせを使用してバッチ挿入を実現できます。しかし、EJB3 がこれをサポートしているかどうかを知りたいです...
5 に答える
JPA も Hibernate もバッチ挿入の特定のサポートを提供しておらず、JPA を使用したバッチ挿入のイディオムは Hibernate の場合と同じです。
EntityManager em = ...;
EntityTransaction tx = em.getTransaction();
tx.begin();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
em.persist(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
em.flush();
em.clear();
}
}
tx.commit();
session.close();
この場合、Hibernate 独自の API を使用しても、IMO の利点はありません。
参考文献
- JPA 1.0 仕様
- 4.10項「一括更新および一括削除操作」
- Hibernate Core リファレンス ガイド
中程度のレコード数を使用すると、次のように使用できます。
em.getTransaction().begin();
for (int i = 1; i <= 100000; i++) {
Point point = new Point(i, i);
em.persist(point);
if ((i % 10000) == 0) {
em.flush();
em.clear();
}
}
em.getTransaction().commit();
ただし、レコード数が多い場合は、このタスクを複数のトランザクションで実行する必要があります。
em.getTransaction().begin();
for (int i = 1; i <= 1000000; i++) {
Point point = new Point(i, i);
em.persist(point);
if ((i % 10000) == 0) {
em.getTransaction().commit();
em.clear();
em.getTransaction().begin();
}
}
em.getTransaction().commit();
参照: JPA バッチストア
特に休止状態については、コアマニュアルの第13章全体でメソッドが説明されています。
しかし、Hibernate を介して EJB メソッドが必要だと言っているので、エンティティ マネージャーのドキュメントには、その章もあります。両方 (コアとエンティティ マネージャー) を読むことをお勧めします。
EJB では、単に EJB-QL を使用するだけです (いくつかの制限があります)。ただし、より柔軟性が必要な場合は、Hibernate がより多くのメカニズムを提供します。
パスカル
commit() は最後にのみ呼び出されるため、100000 レコードを挿入する例では、単一のトランザクション内で行われます。データベースに多くの圧力をかけますか? さらに、ロールバックが発生した場合、コストがかかりすぎます..
次のアプローチはより良いでしょうか?
EntityManager em = ...;
for ( int i=0; i<100000; i++ ) {
if(!em.getTransaction().isActive()) {
em.getTransaction().begin();
}
Customer customer = new Customer(.....);
em.persist(customer);
if ((i+1) % 20 == 0 ) { //20, same as the JDBC batch size
//flush and commit of inserts and release memory:
em.getTransaction().commit();
em.clear();
}
}
session.close();
はい、定義したコントロールを保持するために、必要に応じて JPA 実装にロールバックできます。
JPA 1.0 は EL-HQL が豊富ですが、Criteria API のサポートが不足していますが、これは 2.0 で対処されています。
Session session = (Session) entityManager.getDelegate();
session.setFlushMode(FlushMode.MANUAL);