2009-09-01 12 views
3

私はちょっと非効率なように書かれたフィーチャーに飛び乗りましたが、JPAに関する私の知識は、Hibernate固有ではないポータブルな解決策を見つけるのにはあまり適していません。新しいエンティティのそれぞれを挿入するために、ループ内で呼び出されるダオ方法はない一言で言えばPortable JPA Batch/Bulk Insert

「entityManager.merge(オブジェクト);」。

イマイチ」はダオ方法にエンティティのリストを渡して、代わりに一つ一つのオブジェクトに対してマージ呼び出すのバルク/バッチ挿入を行うにはJPA仕様で定義されている方法はありますか?

プラスダオ方法は、すべての単一のマージ・コールは、独自のトランザクション内で起こっている場合、私は思ったんだけど/「@Transactional」...パフォーマンスを助けないであろうwが注釈されているからです。

答えて

6

ませバニラJPAにはバッチ挿入操作はありません。

はい、各インサートは、独自のトランザクション内で実行されます。 @Transactional属性は、(修飾子なしで)REQUIREDの伝搬レベルを(それが存在しない場合、トランザクションを作成します)を意味します。あなたが持っていると仮定:

public class Dao { 
    @Transactional 
    public void insert(SomeEntity entity) { 
    ... 
    } 
} 

あなたがこれを行う:

インサートのグループ全体を単一のトランザクションに包まれます方法
public class Batch { 
    private Dao dao; 

    @Transactional 
    public void insert(List<SomeEntity> entities) { 
    for (SomeEntity entity : entities) { 
     dao.insert(entity); 
    } 
    } 

    public void setDao(Dao dao) { 
    this.dao = dao; 
    } 
} 

。非常に多数の挿入物について話している場合は、1000、10000などのグループに分割して、十分に大きなコミットされていないトランザクションとして機能するものは、データベースを枯渇させ、サイズだけで失敗する可能性があります。

注:@Transactionalは、春の注釈です。 SpringリファレンスのTransactional Managementを参照してください。あなたは何ができるか

+0

返信いただきありがとうございます。私のDaoメソッドの中では、Merge()の代わりにPersist()を使うのは、新しいエンティティなので役立ちますか? – Lancelot

+0

merge()とpersist()は異なるセマンティクスを持ちます。それは簡単な問題ではなく、私はJPAに関するいくつかの読書を強くお勧めします。 – cletus

0

あなたは狡猾な気分にあった場合は、次のとおりです。

@Entity 
public class SomeEntityBatch { 

    @Id 
    @GeneratedValue 
    private int batchID; 
    @OneToMany(cascade = {PERSIST, MERGE}) 
    private List<SomeEntity> entities; 

    public SomeEntityBatch(List<SomeEntity> entities) { 
     this.entities = entities; 
    } 

} 

List<SomeEntity> entitiesToPersist; 
em.persist(new SomeEntityBatch(entitiesToPersist)); 
// remove the SomeEntityBatch object later 

ためカスケードの、エンティティは、単一の操作で挿入されるようになりますこと。

個々のオブジェクトをループ内に永続させるだけでは、これを実践する上でのメリットはありません。 JPA実装が発行したSQLを見て、ベンチマークするのは面白いことです。