34

JPA EntityManager を使用してバッチ挿入を使用できる方法はありますか。これを実現する直接的な方法がないことはわかっていますが、このメカニズムを実現する何らかの方法が必要です。

実際には、すべての挿入操作で 300 ミリ秒かかりますが、これは、単一の挿入ではなくバッチ挿入を使用して短縮したいと考えています。

これは、単一の挿入で現在実行しているコードです

        @PersistenceContext(unitName = "testing")
        EntityManager eM;

        Query querys = this.eM.createNativeQuery(insertQuery);
        for (String s : someList) {
            //setting parameters
            querys.executeUpdate();
        }

前もって感謝します。

4

4 に答える 4

22

トランザクションがループを囲むかどうかに応じて、通常、バッチ処理は既に発生しています。

JPA はすべての更新を L1 キャッシュに収集し、通常、トランザクションがコミットされると、そのすべてをバッチで DB に書き込みます。これは、更新メソッドを呼び出すまで、追加するすべてのバッチ項目も一時的にメモリ内にある JDBC でのバッチ処理とそれほど違いはありません。

潜在的に問題となるのは、JPA が実際にこのバッチ処理を行うという確固たる保証がなく、トランザクションのコミット時またはしきい値に達したときにこれを行うかどうかですが、実際にはほぼすべてのケースで、特にそのような単純な更新ループ、実際にバッチ処理を行います。

問題の 1 つは、JPA が既にバッチ処理を行っている場合でも、バッチ サイズを制御したい場合があることです。他の回答でリンクされている記事は、そのための非常に役立つ情報を提供します。

最後に、L1 キャッシュがループで増大し続けることに注意する必要があります。そのため、更新の数が非常に多い場合は、定期的にクリアしてください。または、ビジネス ロジックがそれを維持できる場合は、複数のトランザクションで部分的な更新を行います。たとえば、トランザクション 1 では項目 0 から 100.000、トランザクション 2 では 100.001 から 200.000 などです。

于 2012-05-15T09:06:33.510 に答える
20

これはかなり古い質問であり、回答が受け入れられていることを私は知っています。それにもかかわらず、この非常に具体的な主題「JPAバッチ挿入」に対して新しい回答を提供したいと思います。

@PersistenceContext
private EntityManager entityManager;

@Value("${hibernate.jdbc.batch_size}")
private int batchSize;

public <T extends MyClass> Collection<T> bulkSave(Collection<T> entities) {
  final List<T> savedEntities = new ArrayList<T>(entities.size());
  int i = 0;
  for (T t : entities) {
    savedEntities.add(persistOrMerge(t));
    i++;
    if (i % batchSize == 0) {
      // Flush a batch of inserts and release memory.
      entityManager.flush();
      entityManager.clear();
    }
  }
  return savedEntities;
}

private <T extends MyClass> T persistOrMerge(T t) {
  if (t.getId() == null) {
    entityManager.persist(t);
    return t;
  } else {
    return entityManager.merge(t);
  }
}

ソース: http://frightanic.com/software-development/jpa-batch-inserts/

于 2015-06-24T07:59:22.560 に答える
12

JPA を使用してバッチ書き込みを実行すること可能ですが、永続化プロバイダー、データベース、および JDBC ドライバーの特定の実装に大きく依存します。たとえば、この記事では、EclipseLink JPA 2.3 と Oracle データベースを使用してバッチ書き込み (最適化 #8) を有効にする方法について説明します。特定の環境で同様の構成パラメーターを探してください。

于 2012-05-14T13:53:48.553 に答える
3

JPA 自体には、バッチ処理の設定はありません。ただし、実装に依存する設定がいくつかあります。これは hibernate の例です

于 2012-05-14T13:55:03.457 に答える