Hibernate, путаница родителей / детей - PullRequest
1 голос
/ 07 сентября 2011

У меня есть простое объектное отношение, я хочу сохранить его в спящем режиме.

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

Это делается в среде GWT, поэтому я передаю ChildDTO этому методу, который в основном является непостоянной версией класса Child (несовместимой с сериализацией RPC gwts).

public Integer testHibernate(Integer parentId, ChildDTO[] test) {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();

    Parent model;
    if(parentId == null) {
        // if the parentId is null, create new instance 
        model = new Parent ); 
    }
    else {
        model = (Parent) hib.load(Parent.class, dto.getId());
    }

    model.setName("dummy name");

    for(int i = 0; i < test.length) {
        model.addChild(new Child(test[i].getId(), test[i].getName()));
    }

    hib.save(model);        
    hib.getTransaction().commit();

    return model.getId();
}

Правильно, это прекрасно работает для создания новых родителей, без детей. Это также работает нормально, если я просто добавляю одного ребенка к существующему родителю. Однако, если я добавляю более одного дочернего элемента, я получаю сообщение об ошибке «невозможно вставить» из спящего режима.

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

Дополнительный вопрос. При вставке только одного дочернего элемента в пустой родительский hibernate выполняет следующие действия:

Hibernate: insert into Child(ChildId, ChildName) values (default, ?)
Hibernate: update Parent set ChildId=? where ChildId=? 

Что с обновлением? : S

1 Ответ

2 голосов
/ 07 сентября 2011

Однако, если я добавлю более одного дочернего элемента, я получу сообщение «невозможно вставить» ошибка из спящего режима .

Из вопроса кажется , что отношение Родитель-Ребенок было установлено как один-к-одному, а не как один-ко-многим. Сначала убедитесь, что это правильно в вашем конфигурационном файле hibernate.

<set name="children">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>

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

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

for(int i = 0; i < test.length) {
        model.addChild(new Child(test[i].getId(), test[i].getName()));
    }

При вставке только одного дочернего элемента в пустой родительский следующее:

Это логично, первый оператор INSERT соответствует новой строке для объекта Child. Второй оператор UPDATE соответствует установлению связи между объектами Parent и Child.

Вы можете оптимизировать это, установив отношение inverse. В этом сценарии таблица Child хранит parent_id и, следовательно, приводит к одному оператору INSERT, чем к двум операторам.

<set name="children" inverse="true">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>

См. Эту ссылку в документации Hibernate, в которой четко объясняется, как настроить и реализовать отношение Parent-Child: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-parentchild.html#example-parentchild-bidir

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...