1

我有一个像这样的对象层次结构(忽略所有字段,如 id、setter/getter 等):

@Entity
class A {
    @OneToOne(cascade=CascadeType.ALL)
    private B b;
}

@Entity
class B {
    @OneToOne(cascade=CascadeType.ALL)
    private A a;

    @OneToOne(cascade=CascadeType.ALL)
    private C c;
}

@Entity
class C {
    private int x;
}

所有实体都有@Id @GeneratedValue private Long id;

我将 JPA 与 Hibernate 和 MySQL 一起使用,并有一个 DAO 可以为A它做一个简单的entityManager.merge(a); entityManager.flush();

现在,这个结构被用在一个 JSF 项目中,我A用一个新的创建了一个新的,B但值C是从数据库中获取的,因此它是一个现有的实体。这个新填充的对象显示在页面上,并且仅在我单击保存按钮时才保存,因此创建和保存是在两个不同的事务中完成的。

当我尝试 do adao.save(a)时,我得到一个org.hibernate.TransientObjectException,这并不奇怪,因为cin 类的值B已经存在于数据库中。

现在的实际问题是:我可以在不手动级联保存的情况下以某种方式避免这个问题吗?我说的是几十个B-type 类,每个类都有几十个Cs - 这完全违背了我的级联想法......

任何想法表示赞赏!

4

2 回答 2

0

There may be a problem due to annotation. You can get help from this Example to solve your problem.

于 2012-11-13T09:43:14.213 回答
0

我通过执行以下操作解决了这个问题:

A中,我创建了一个List<B> getBs()获取所有 B 类的方法。在B中,我创建了一个方法List<C> getCs()。现在,在我做的道

public void save(A a) {
    for (B b : a.getBs()) {
        for (C c : b.getCs()) {
            if (c != null) {
                if (c.getId() == null) {
                    entityManager.persist(c);
                } else {
                    entityManager.merge(c);
                }
            }
        }
    }
    super.save(a);
}

现在我只需要跟踪Bs和Cs,但它仍然比遍历整个对象树要好......

于 2012-11-13T11:09:35.113 回答