【问题标题】:Eclipselink OneToMany Merge Deletes RelationsEclipselink OneToMany 合并删除关系
【发布时间】:2012-03-23 14:43:15
【问题描述】:

我有一个与对象提交具有一对多关系的父对象 Compound。我已经建立了如下关系:

@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 对象上。提交数据未存储在表单中,因此新 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);
}

接下来我将我构建的复合对象合并到持久化上下文中。

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(Compound) 方法时,我期望忽略提交数据的缺失。但是,情况并非如此,任何与我正在修改的化合物相关的提交都将被删除。

我一定是做错了什么或者误解了 CascadeType.MERGE 的含义?有人可以帮忙吗?

谢谢 詹姆斯

【问题讨论】:

    标签: jpa merge eclipselink cascade


    【解决方案1】:

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

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

    【讨论】:

    • 嗨,克里斯。感谢您的回答。我认为你是对的,我误解了 CascadeType.MERGE 指示的行为 - 这决定了是否合并每个引用的提交中的更改,而不是是否合并特定化合物引用的提交列表。谢谢你的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多