2013-09-11 3 views
0

Мне нужно создать кучу объектов программно и сохранить их все. Есть 1:n, 1:1 и n:n отношения, связанные в то же время.Сохранение нескольких объектов и их отношений (Cascade.All/ManyToMany)

Все отношения определены с помощью CascadeType.All.

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

Пример:

A a1 = new A(); 
A a2 = new A(); 
A a3 = new A(); 

CommonB = new B(); 
SpecialB = new B(); 

Set<B> set1 = new HashSet<B>(); 
set1.add(CommonB); 
set1.add(SpecialB); 

Set<B> set2 = new HashSet<B>(); 
set2.add(CommonB); 

a1.setBs(set1); 
a2.setBs(set2); 
a3.setBs(set2); 

Теперь я использую наш DataService упорствовать a1, a2 и a3. (Это в основном только звонки сохраняются() на EntityManager)

Первая попытка работает хорошо, оба, CommonB и SpecialB, сохраняются вместе с a1 (также отношения созданы. Однако, когда я пытаюсь оставаться a2, Hibernate говорит org.hibernate.PersistentObjectException: detached entity passed to persist: my.namespace.B

Классы выглядеть следующим образом:

class A(){ 
    @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }) 
    @JoinTable 
    private Set<B> bs; 

    //get set 
} 

class B(){ 
    @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, mappedBy = "bs") 
    private Set<A> as; 
} 

пример был лишен вниз, на самом деле существует множество n:n отношений между 5 субъектов

.

--- обновление

я пропустил, чтобы добавить "как" к "Bs" Set, а также:

CommonB.setAs(/* a1, a2, a3 */); 
SpecialB.setAs(/* a1 */); 

Итак, говоря полные отношения являются набор на уровне объекта. Не должно Cascade.All действительно заботиться о сохранении ВСЕХ объектов в пределах определенного связывания отношений, когда я сохраняю ОДИН из этих объектов?

Если я дать как em.persist(a1), не зимуют уведомление:

  • a1 связан с CommonB и специальным В.
  • CommonB в свою очередь, связан с a2 и a3
  • Так я сохраняя a1, a2, a3, CommonB и SpecialB.

Однако это не произойдет ..

ответ

2

Когда вы упорно a1, он также сохраняется в CommonB и устанавливает идентификатор в этот объект. Стойкая a2 будет пытаться сохранить CommonB еще раз, когда она была сохранена один раз. Я предполагаю, что ваш dataservice является Transactional, поэтому после сохранения a1 он закрывает сессию TX и Hibernate, тогда CommonB становится отдельным объектом. Вам необходимо перезагрузить (повторно подключить) CommonB при сохранении a2 и a3.

+0

Это правда. Я также забыл добавить «обратные» отношения. Я исправил его сейчас, поэтому «нормальный» я должен иметь возможность сохранять ВСЕ объекты, когда они будут сохраняться один раз (см. Мое редактирование), однако этого не произойдет.:( – dognose

Смежные вопросы