【问题标题】:JPA/EclipseLink: disable cascade for certain merge operations?JPA/EclipseLink:禁用某些合并操作的级联?
【发布时间】:2012-11-14 15:55:14
【问题描述】:

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

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

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

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

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

所以我想知道在我忽略的地方是否有更好的答案?感谢您提供任何信息。

【问题讨论】:

    标签: jpa merge eclipselink cascade toplink


    【解决方案1】:

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

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

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

    【讨论】:

    • 知道如何使用 NO_CASCADE 吗?
    • @Aguid 有任何解决方案吗?
    • 您是否按照建议尝试使用 shallowMergeClone?
    猜你喜欢
    • 2012-08-11
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多