我有一个父对象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的含义?有人可以帮忙吗?
由于 詹姆斯
答案 0 :(得分:2)
两个问题:
1)您标记了与@PrivateOwned的关系,这将导致所有解除引用的实体也被删除。
2)你正在合并一个空集合。级联合并(或缺少合并)仅意味着合并将(或将不会)级联到提交实体。虽然集合本身的状态被认为是化合物的一部分,因此需要在数据库中进行更新。加上#1,这意味着将删除提交。如果不是#1,则数据库中不会有任何变化(因为提交内容拥有关系并且没有更改),但是当读回复合实体时,除非刷新,否则它将显示空或空集合。
创建实体的新实例是个坏主意。相反,您可能希望将其读入并仅更改表单中所需的内容 - 然后在需要时将此实体合并到事务上下文中。