坚持多个实体及其关系(Cascade.All / ManyToMany)

时间:2013-09-11 09:04:42

标签: java mysql hibernate jpa

我需要以编程方式创建一堆对象并将它们全部保留下来。 同时涉及1:n1:1n: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())

第一次尝试效果很好,CommonBSpecialB都与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)那样给出,请不要休眠注意:

  • a1与CommonB和Special B有关。
  • CommonB依次与a2和a3
  • 相关
  • 所以我要保存a1,a2,a3,CommonB和SpecialB。

然而,这不会发生..

1 个答案:

答案 0 :(得分:2)

当您保留a1时,它还会保留CommonB并将ID设置为该对象。坚持a2会在CommonB持续一次后再次尝试保留a1。我假设你的dataservice是Transactional,所以在持久化CommonB后它会关闭TX和Hibernate的会话,然后CommonB成为一个分离的对象。持久a2a3时,您需要重新加载(重新附加){{1}}。