0

現在、次のようなオブジェクトがあります(他のメンバー変数も):

public class Parent {
    private Set<Child> children = new HashSet<Child>;

    @OneToMany(cascade = { CascadeType.PERSIST,
        CascadeType.MERGE }, fetch = FetchType.LAZY)
    public Set<Child> getChildren() {
        return children;
    }
    public setChildren(Set<Child> children) {
        this.children = children;
    }
}

Child クラスは、その Parent オブジェクトだけでなく、それ自身の子への参照も持ちます。その子のそれぞれにも、所有している Child オブジェクトへの参照があります。

私はこれが多くの循環参照であることを理解していますが、この時点でモデルを変更することは実際には実行可能ではありません:(

永続化のために、次のようなものがあります。

private void persist(List<Parent> parents) {
    synchronized(parentDAO) {
         parentDao.startTx();
    try {
        for ( Parent parent : parents ) {
             parentDao.merge( parent );
    } catch (Exception e) {
         parentDao.rollback();
    }
    parentDao.commit();

}

parentDao は基本的に、さまざまなエンティティ マネージャー関数をラップするだけです (つまり、parentDao.startTx() は EntityManager.getTransaction().begin() を呼び出し、parentDao.merge() は EntityManager.merge() を呼び出します)。

サイズが 11,000 以上のセットを持つ親をマージしようとしています。マージには 7 時間以上かかります。夜間に実行する必要がある多数のデータベース操作があり、この 1 回の呼び出しが割り当てられた時間の大部分を占めているため、可能な限り短縮する必要があります。

この操作を高速化するためのオプションは何ですか? Set を小さなセットに分割して作業単位を削減し (同僚は一度に 100 個の子オブジェクトを提案しました)、parentDao.merge(Set ) を呼び出すことは 1 つのオプションですが、実際には操作全体を高速化できますか? Aこの操作を高速化する他の方法はありますか? このプロセスはさまざまな環境で毎週実行されることになっているため、db ダンプの生成やスクリプトの実行などの手動操作は問題外です。

データベースには Oracle を使用し、Hibernate 3.6.6 を使用しています。

ありがとう!!

4

0 に答える 0