Я пытаюсь выполнить каскадное сохранение на крупном объектном графе с использованием JPA. Например (мой график объект немного больше, но достаточно близко):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+ Б. Код только
em.persist(a);
Проблема в том, что она МЕДЛЕННАЯ. Мое сохранение занимает приблизительно 1300 мс. Я посмотрел на генерируемый 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 и зимуют также. Бэкэнд - оракул 11g. Проблема в том, как скомпилирован sql. Каждая из этих операций выполняется дискретно, а не навалом, поэтому, если есть сетевая латентность даже 5 мс между моим сервером приложений и сервером db, выполнение 200 дискретных операций добавляет 1 секунду. Я попытался увеличить выделение в моих последовательностях, но это немного помогает. Я также попытался прямым JDBC в качестве пакетного высказывания:
for...{
statement = connection.prepareStatement(sql);
statement.addBatch();
}
statement.executeBatch();
Для моей DataModel это занимает около 33ms сделано как прямой JDBC партии. Сам Oracle принимает 5 мс для 100 + вставок.
Есть ли способ сделать JPA (я застрял с 1.0 прямо сейчас ...) идти быстрее, не вникая в конкретные вещи поставщика, такие как вставка для спящего режима?
Спасибо!
благодарит за отзыв! Будет опубликовать то, что я сделал ниже! – user364939
Спасибо за информацию, очень приятно – Greg