我需要以编程方式创建一堆对象并将它们全部保留下来。
同时涉及1:n
,1:1
和n:n
关系。
所有关系均以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上调用persist())
第一次尝试效果很好,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;
}
示例已被删除,事实上5个实体之间存在多个n:n
关系。
---更新
我错过了将“As”添加到“Bs”Set中:
CommonB.setAs(/* a1, a2, a3 */);
SpecialB.setAs(/* a1 */);
所以,说完对象是在对象级别上设置。
每当我保存其中一个对象时,Cascade.All
实际上不应该在某个关系束中持久保存所有对象吗?
如果我像em.persist(a1)
那样给出,请不要休眠注意:
然而,这不会发生..
答案 0 :(得分:2)
当您保留a1
时,它还会保留CommonB
并将ID设置为该对象。坚持a2
会在CommonB
持续一次后再次尝试保留a1
。我假设你的dataservice是Transactional,所以在持久化CommonB
后它会关闭TX和Hibernate的会话,然后CommonB
成为一个分离的对象。持久a2
和a3
时,您需要重新加载(重新附加){{1}}。