JPAを使用してラージオブジェクトグラフをカスケード保存しようとしています。たとえば(私のオブジェクトグラフは少し大きいですが、十分に近いです):
@Entity
@Table(name="a")
public class A {
private long id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "a")
private Collection<B> bs;
}
@Entity
@Table(name="b")
public class B {
private long id;
@ManyToOne
private A a;
}
だから私は100以上のBのコレクションを持つAを永続化しようとしています。コードはただです
em.persist(a);
問題は、それが遅いということです。私の節約は約1300msかかります。生成されているSQLを調べましたが、非常に非効率的です。このようなもの:
select a_seq.nextval from dual;
select b_seq.nextval from dual;
select b_seq.nextval from dual;
select b_seq.nextval from dual;
...
insert into a (id) values (1);
insert into b (id, fk) values (1, 1);
insert into b (id, fk) values (2, 1);
insert into b (id, fk) values (3, 1);
...
現在、永続性プロバイダーとしてtoplinkを使用していますが、eclipselinkとhibernateも試しました。バックエンドはoracle11gです。問題は、実際にはSQLをどのように組み合わせるかです。これらの各操作は一括ではなく個別に実行されるため、appserverとdbサーバーの間に5ミリ秒のネットワーク遅延がある場合、200回の個別操作を実行すると1秒追加されます。シーケンスのallocationSizeを増やしてみましたが、それは少ししか役に立ちません。また、直接JDBCをバッチステートメントとして試しました。
for...{
statement = connection.prepareStatement(sql);
statement.addBatch();
}
statement.executeBatch();
私のデータモデルの場合、直接JDBCバッチとして実行されるのに約33ミリ秒かかります。Oracle自体は、100以上の挿入に5ミリ秒かかります。
とにかく、休止状態のバルクインサートのようなベンダー固有のものを掘り下げることなく、JPA(私は今1.0で立ち往生しています...)をより速くする方法はありますか?
ありがとう!