【问题标题】:Does EntityManager refresh() cause to cascade synchronization through entities multi-level relation?EntityManager refresh() 是否会导致通过实体多级关系进行级联同步?
【发布时间】:2012-08-29 19:23:03
【问题描述】:

我有三个实体“A”、“B”、“C”:


@Entity
public class A implements Serializable {
    ... 

    private B b;  

    @OneToOne(mappedBy = "a", fetch = FetchType.LAZY)
    @Cascade({CascadeType.ALL})
    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    } 

    ...
}

@Entity
public class B implements Serializable {
    ...

    private A a;

    @OneToOne(fetch = FetchType.LAZY)
    public A getA() {
         return a;
    }

    public void setA(A a) {
         this.a = a;
    }

    ...

    private Collection<C> cCollection;

    @OneToMany(mappedBy = "b", fetch = FetchType.LAZY)
    public Collection<C> getCCollection() {
        return cCollection;
    }

    public void setCCollection(Collection<C> cCollection) {
        this.cCollection = cCollection;
    }
    ...
}

@Entity
public class C implements Serializable {
    ...

    private B b;
    @ManyToOne(optional = false, fetch = FetchType.LAZY )
    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b= b;
    }
}

当我更新 B.cCollection - 添加或删除 C 对象 - 然后刷新对象 a 时,我预计这些更改会影响 a.getB().getCCollection() 的结果,但它永远不会发生并且 cCollection 列表不会不会更新。我对 refresh() 操作有误吗?

//Adding or removal C objects to/from a.getB().getCCollection()
//Persisting changes
myEM.refresh(a);

(注意:我使用的是hibernate和JPA 2.0。在数据库中持久化数据没有问题,并且确实有效。

【问题讨论】:

    标签: hibernate jpa-2.0 entitymanager


    【解决方案1】:

    【讨论】:

    • 是的,没有注意到你没有为 b.getCCollection() 设置级联。您可以设置级联属性或在 b 上调用合并。
    • 顺便说一句,当您从 a.getB().getCCollection() 更新 C 对象时,您的 A 对象是托管对象吗?
    • 逻辑上,如果我刷新'a',它的所有基本和关系字段都必须刷新!!(如果我错了,请更正)。所以当我调用 a.getB().getCCollection() 时,它必须返回 c 的新集合(新的持久化集合)。我也应该刷新“a”的“b”对象吗?
    • 例如:a.getB().getCCollection().add(new C(/*arguments*/)); myEM.getTransaction().begin(); myEM.merge(a.getB()); myEM.getTransaction().commit(); myEM.refresh(a)
    • 刷新仅意味着它从数据库而不是会话中检索对象的状态。那么在调用 refresh() 之前,您确定您的更改已刷新到数据库吗?
    【解决方案2】:

    “使用 refresh() 方法可以随时重新加载对象及其所有集合。这在使用数据库触发器初始化对象的某些属性时很有用。”

    “Hibernate 从数据库加载多少,它将使用多少 SQL SELECT?这取决于获取策略。”

    更多详情请访问Chapter 10: Working with Objects

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多