JPA / EclipseLink:禁用某些合并操作的级联?

时间:2012-11-14 15:55:14

标签: jpa merge eclipselink cascade toplink

我正在使用EclipseLink 2.3.3。使用包含大约100个实体的数据模型。我有一个使用注释映射到每个数据库表的Java类。

我有两个用例要实现。一个是新记录进入系统,大约60-75个表。对于这种情况,我希望合并并持久化级联,这样我就可以合并顶级对象并将其级联到所有相关实体。

另一个用例是我需要插入一组单独的对象,通常是来自一堆不同表中的一个。在这种情况下,我不希望级联合并,因为我需要控制插入。如果我启用了级联,合并第一个对象可能会也可能不会合并其他对象,具体取决于它们是否或如何相关,所以我宁愿明确合并它们。

基本上,我希望级联合并并在一种情况下持续存在,而不是另一种情况。因此,如果我在映射类中包含级联注释,我需要有选择地禁用某些操作的级联;或者,如果我在映射的类中关闭级联,我想为某些操作启用级联。

到目前为止,我没有找到任何方法来选择性地打开或关闭特定操作的级联。有一个CascadePolicy类,但似乎只用于查询。有动态实体,我想也许我可以使用它来做一些事情,比如从现有实体创建一个动态实体,关闭该实体关系的级联行为,并以某种方式使用它进行合并,但我无法做到为此找到合适的API。

所以我想知道在某个地方有一个更好的答案,我忽略了吗?感谢您提供任何信息。

1 个答案:

答案 0 :(得分:1)

我不确定您的控制级别,特别是在您提到要插入单个对象的情况下。从它的声音来看,级联合并正是你想要的Entity对象树,在第一种情况下与EntityManager.merge一起使用。调用实体的合并将检查它是否是新的,并根据需要更新或插入。将关系标记为级联合并将允许查找新对象并将其插入。

第二种情况虽然您想要处理单个插入,但为什么不在映射上排除cascade persist选项,只需要在要插入的对象上调用EntityManager.persist? Persist则不会级联,因此只有你调用em.persist的实体才会被插入。关系将仅用于设置foreignkey值 - 尽管您可能希望将它们排除在外,然后将它们设置为较大的合并调用的一部分。需要维护双向关系的双方,如果另一方存在且未合并,则不存储其关系变化。

如果这不是您想要的,则EclipseLink在UnitOfWork上具有本机API(EntityManager实际上包装了一个用于事务工作的UnitOfWork),允许您指定合并策略。请参阅UnitOfWork上的mergeClone,deepMergeClone和shallowMergeClone,它们分别使用CASCADE_ALL_PARTS,CASCADE_PRIVATE_PARTS和NO_CASCADE作为合并策略,而JPA合并则使用CASCADE_BY_MAPPING。