JPA Hibernate пакетная вставка один ко многим - PullRequest
1 голос
/ 25 марта 2011

учитывая этот сценарий:

    class Parent {
     private Integer id;
     private String name;
     @oneToMany(mappedBy="father")
     private List<Child> children;
     ... ...
    }

    class Child {
     private Integer id;
     private String name;
     @ManyToOne (optional="false")
     @JoinColumn(name="id")
     private Parent father;
     ........
}


Class MyParentService{

     public Parent parentService(List<Child> childList){
        em.getTransaction.begin();
        Parent parent = new Parent();
        parent.setChildren(childList);
        em.persist(parent);
        em.getTransaction.commit();
   }
}

Я получу исключение org.hibernate.PropertyValueException: not-null property references a null or transient

потому что атрибут отца является "необязательно = ложно"

, поэтому я должен заменить parent.setChildren(childList); и выполнить такой цикл в parentService ():

for(Child c: childList){
 c.setFather(parent.getId());
 parent.getChildrent().add(c);
}

это правильно? Есть ли лучший способ обойтись без повторного зацикливания childList?

Ответы [ 2 ]

3 голосов
/ 25 марта 2011

Работая с Hibernate, вы несете ответственность за поддержание согласованного состояния обеих сторон двунаправленных отношений. Более того, при сохранении отношений Hibernate смотрит на сторону-владельца (сторону без mappedBy), поэтому ваш код не будет правильным даже без optional=false.

Вы можете использовать следующий подход для обеспечения согласованности:

class Parent {
    ...
    public void addChild(Child c) {
        children.add(c);
        c.setParent(this);
    }
}

public Parent parentService(List<Child> childList) {
    ...
    for (Child c: childList) {
        parent.addChild(c);
    }
    ...
} 

В этом случае видимость setChildren() может быть ограничена во избежание ошибочных вызовов.

Кроме того, выглядит странным, что у вас нет каскадирования и не сохраняются дочерние элементы в одной транзакции с родительским.

0 голосов
/ 25 марта 2011

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

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