Массовая вставка через Spring/Hibernate, где необходимы идентификаторы

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

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);
        }
    }
}

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

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;
}

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


person user973479    schedule 21.12.2011    source источник


Ответы (3)


Если вы определяете отношения с помощью аннотаций и определяете соответствующее каскадирование, вы должны иметь возможность устанавливать отношения объектов в объектах в 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)
person JustinKSU    schedule 21.12.2011
comment
У вас есть пример этого? Я не уверен, что вы подразумеваете под аннотациями и соответствующим каскадированием. - person user973479; 21.12.2011
comment
Если я просто попытаюсь сохранить objFour (который теоретически сохранит все остальное), я получаю сообщение об ошибке org.hibernate.PropertyValueException: свойство not-null ссылается на нулевое или переходное значение - person user973479; 21.12.2011
comment
Используете ли вы XML или аннотации для настройки Hibernate? - person JustinKSU; 21.12.2011
comment
Я использую аннотации. Я только что понял, я думаю... (cascade = CascadeType.ALL). Я нашел пример здесь: mkyong .com/спящий режим/ - person user973479; 21.12.2011

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

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

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

person helios    schedule 21.12.2011

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

person John Pickup    schedule 21.12.2011