23

JPA/EJB3 フレームワークは、バッチ挿入操作を行う標準的な方法を提供していますか? 永続化フレームワークに hibernate を使用しているため、Hibernate Session にフォールバックし、session.save()/session.flush() の組み合わせを使用してバッチ挿入を実現できます。しかし、EJB3 がこれをサポートしているかどうかを知りたいです...

4

5 に答える 5

22

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 リファレンス ガイド
于 2010-09-02T01:26:11.307 に答える
5

中程度のレコード数を使用すると、次のように使用できます。

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 バッチストア

于 2014-04-03T05:00:47.620 に答える
5

特に休止状態については、コアマニュアルの第13章全体でメソッドが説明されています。

しかし、Hibernate を介して EJB メソッドが必要だと言っているので、エンティティ マネージャーのドキュメントには、その章もあります。両方 (コアとエンティティ マネージャー) を読むことをお勧めします。

EJB では、単に EJB-QL を使用するだけです (いくつかの制限があります)。ただし、より柔軟性が必要な場合は、Hibernate がより多くのメカニズムを提供します。

于 2009-01-15T20:05:04.753 に答える
1

パスカル

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();
于 2013-12-13T15:30:43.453 に答える
1

はい、定義したコントロールを保持するために、必要に応じて JPA 実装にロールバックできます。

JPA 1.0 は EL-HQL が豊富ですが、Criteria API のサポートが不足していますが、これは 2.0 で対処されています。

Session session = (Session) entityManager.getDelegate();
session.setFlushMode(FlushMode.MANUAL);
于 2009-07-06T10:27:58.333 に答える