Принудительно установить транзитивный порядок сохранения в JPA 2 с Hibernate? - PullRequest
2 голосов
/ 09 сентября 2011

Можно ли как-то изменить порядок сохранения объектов в JPA 2 с Hibernate?

Скажем, у меня есть три класса: Parent, Child и Desk. Parent владеет коллекциями Child и Desk через @OneToMany; Child может иметь один Desk. Кроме того, Parent определяет транзитивное постоянство в обеих коллекциях, но Child не определяет транзитивное постоянство в его Desk:

class Parent {
    @OneToMany(cascade=CascadeType.ALL) Collection<Child> children;
    @OneToMany(cascade=CascadeType.ALL) Collection<Desk> desks;
    ...
}

class Child {
    @OneToOne(cascade={}) Desk desk;
    @ManyToOne Parent parent;
}

class Desk {
    @ManyToOne Parent parent;
}

В идеале, я хотел бы создать Письмо и Ребенка одновременно и сохранить отношения:

Parent parent = em.find(...);
Child child = new Child();
Desk desk = new Desk();
// add both desk and child to parent collections here
// set Parent attribute on both desk and child

Если я выполняю приведенный выше код в транзакции, Hibernate переходит от Parent к новому Child и пытается сохранить новый объект Child. К сожалению, это приводит к ошибке «объект ссылается на несохраненный временный экземпляр», поскольку каскад с Parent до Desk не привел к сохранению нового объекта Desk.

Я знаю, что могу исправить проблему с помощью операции EntityManager flush () (em.flush()) - создайте Child, создайте Desk, присоедините оба к Parent, em.flush(), затем присоедините * От 1034 * до Child, но я не очень-то увлекаюсь засорением своего кода с помощью em.flush() для сохранения сложных графиков новых постоянных объектов. Есть ли другой способ сообщить JPA 2 или Hibernate о том, что он всегда должен сначала сохранять новый Desk вместо нового Child?

1 Ответ

1 голос
/ 09 сентября 2011

Глядя на ваше описание, я думаю, что система постоянства пытается сначала сохраниться в следующем порядке:

  • Сначала Parent.children [i]
  • Each Children [i]имеет временный указатель на Desk.Системе не удается сохранить его, потому что вы не настроили его как Cascade.Persist.

Затем происходит сбой при сохранении Desk, и вы думаете, что он потерпел неудачу в пути Parent.desks [i] (которыйнастроен как каскадный), но, возможно, сбой происходит не по этому пути.

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