Массовая вставка через Spring / Hibernate, где нужны идентификаторы - PullRequest
1 голос
/ 21 декабря 2011

Я должен сделать массовые вставки, и мне нужны идентификаторы того, что добавляется. Это базовый пример, который показывает, что я делаю (что явно ужасно для производительности). Я ищу гораздо лучший способ сделать это.

public void omgThisIsSlow(final Set<ObjectOne> objOneSet,
                          final Set<ObjectTwo> objTwoSet) {
    for (final ObjectOne objOne : objOneSet) {
        persist(objOne);
        for (final ObjThree objThree : objOne.getObjThreeSet()) {
            objThree.setObjOne(objOne);
            persist(objThree);
        }
        for (final ObjectTwo objTwo : objTwoSet) {
            final ObjectTwo objTwoCopy = new ObjTwo();
            objTwoCopy.setFoo(objTwo.getFoo());                
            objTwoCopy.setBar(objTwo.getBar());
            persist(objTwoCopy);

            final ObjectFour objFour = new ObjectFour();
            objFour.setObjOne(objOne);
            objFour.setObjTwo(objTwoCopy);
            persist(objFour);
        }
    }
}

В вышеприведенном случае сохраняется метод, который внутренне вызывает

sessionFactory.getCurrentSession().saveOrUpdate();

Существует ли какой-либо оптимизированный способ получения идентификаторов и массовой вставки на основе этого?

Спасибо!

Обновление: получил работу со следующими дополнениями и помощью от JustinKSU

import javax.persistence.*;
@Entity
public class ObjectFour{
  @ManyToOne(cascade = CascadeType.ALL)
  private ObjectOne objOne;
  @ManyToOne(cascade = CascadeType.ALL)
  private ObjectTwo objTwo;
}

// И аналогично для других классов и их объектов, которые необходимо сохранить

Ответы [ 3 ]

2 голосов
/ 21 декабря 2011

Если вы определяете отношения с помощью аннотаций и определяете соответствующее каскадирование, вы должны иметь возможность устанавливать отношения объектов в объектах в Java и сохранять их все в одном вызове. Hibernate выполнит настройку внешних ключей для вас.

Документация - http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association

Примером аннотации для родительского объекта будет

@OneToMany(mappedBy = "foo", fetch = FetchType.LAZY, cascade=CascadeType.ALL)

На дочернем объекте вы должны сделать следующее

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COLUMN_NAME", nullable = false)
1 голос
/ 21 декабря 2011

Я не уверен, но Hibernate делает массовые вставки / обновления.Проблема, которую я понимаю, заключается в том, что вам необходимо сохранить родительский объект, чтобы назначить ссылку на дочерний объект.

Я бы попытался сохранить все «один» объект.Затем выполните итерацию по всем их «трем» объектам и сохраните их во второй массовой вставке.

Если ваше дерево имеет три уровня, вы можете выполнить все вставки в 3 пакетах.Я думаю, довольно прилично.

0 голосов
/ 21 декабря 2011

Предполагая, что вы просто пытаетесь получить большой объем данных, сохраняемых за один раз, и ваша проблема в том, что вы не знаете, какими будут идентификаторы, поскольку различные связанные объекты сохраняются, одно из возможных решений для этого состоит в том, чтобы запустить все ваши вставки (как массовые вставки) во вспомогательные таблицы (по одной на реальную таблицу) с временными идентификаторами (и некоторыми идентификаторами сеансов) и иметь хранимую процедуру, выполняющую вставки в реальные таблицы, одновременно обрабатывая идентификаторы.

...