Eclipselink OneToMany Merge删除关系

时间:2012-03-23 14:43:16

标签: jpa merge eclipselink cascade

我有一个父对象Compound,它与一个对象Submission有一对多的关系。我建立了如下关系:

@Entity
public class Compound implements Serializable {

    @Id
    private long compoundId;

    ...

    @OneToMany(mappedBy="compound", fetch=FetchType.LAZY,
        cascade={ CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE })
    @PrivateOwned
    private List<Submission> submissions;

    ...
}

@Entity
public class Submission implements Serializable {

    @Id
    private long submissionId;

    ...

    @ManyToOne(fetch=FetchType.LAZY,
        cascade={ CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE })
    @JoinColumn(name="compoundId")
    private Compound compound;

    ...
}

我已经设置了一个表单(在Flex中)来修改所选的化合物。给定表单输出(一个名为ObjectProxy的BlazeDS类,它扩展了HashMap),我将表单中的值映射到一个新的Compound对象。提交数据未存储在表单中,因此新化合物对象上的提交列表保持为空。

public Compound decodeWebForm(final ObjectProxy proxy) {
    // create a new compound object
    final Compound c = new Compound();

    // map the proxy values onto the new compound
    c.setCompoundId(proxy.get("compoundId"));
    ...

    return updateCompound(c);
}

接下来,我将我构造的Compound对象合并到持久化上下文中。

public Compound updateCompound(final Compound c) {
    // retrieve the entity manager
    final EntityManager em = getEntityManager();

    // begin a transaction
    em.getTransaction().begin();

    // merge changes to the managed compound
    final Compound managed = em.merge(c);

    // commit changes to the database
    em.getTransaction().commit();

    return managed;
}

我已经从关系定义中特别省略了CascadeType.MERGE指令。因此,当我调用EntityManager.merge(复合)方法时,我期望缺少提交数据。但是,情况并非如此,任何与我正在修改的化合物相关的提交都将被删除。

我必须做错事或误解CascadeType.MERGE的含义?有人可以帮忙吗?

由于 詹姆斯

1 个答案:

答案 0 :(得分:2)

两个问题: 1)您标记了与@PrivateOwned的关系,这将导致所有解除引用的实体也被删除。
2)你正在合并一个空集合。级联合并(或缺少合并)仅意味着合并将(或将不会)级联到提交实体。虽然集合本身的状态被认为是化合物的一部分,因此需要在数据库中进行更新。加上#1,这意味着将删除提交。如果不是#1,则数据库中不会有任何变化(因为提交内容拥有关系并且没有更改),但是当读回复合实体时,除非刷新,否则它将显示空或空集合。

创建实体的新实例是个坏主意。相反,您可能希望将其读入并仅更改表单中所需的内容 - 然后在需要时将此实体合并到事务上下文中。