【问题标题】:JDO in AppEngine: keep the original entity when deleting from unowned relationshipAppEngine中的JDO:从无主关系中删除时保留原始实体
【发布时间】:2012-08-07 10:41:03
【问题描述】:

我使用 JDO 3.0 语法定义了一个无主关系:

@Persistent
@Unowned
private Set<Role> roles;

我有几个应该分配给用户的预定义角色。我使用以下代码为用户添加/删除角色:

roles.add(roleEntity);
roles.remove(roleEntity); 

问题是这样删除也会从数据存储中删除原始实体,但我只想删除引用。我知道我只能在父实体中存储可以解决问题的密钥,但是有更好的解决方案吗?使用这种“自然”的语法?

【问题讨论】:

  • AFAIK,无主关系从不依赖,所以这不应该发生。 OTOH,如果您的 Role 被序列化 (@Persistent(serialized=true)) 或嵌入 (@Embedded),则可能会发生这种情况。
  • 无主关系可以依赖或不依赖于标准级联删除设置...对于 GAE 或任何数据存储...显然任何问题的定义都不完整
  • 这就是问题所在!就我而言,无主关系表现得像依赖关系。我不知道这怎么可能。唯一的例外是当我调用roles.clear() 时,引用被删除但原始对象保留在数据存储中。但是,当我使用循环遍历角色并为每个角色调用 roles.remove(role) 时,它也会从数据存储中删除原始实体。
  • “文档”是 JDO 规范,公开可用,推荐任何使用 JDO 的人阅读。我认为 DataNucleus 文档也很好地涵盖了这些内容。谷歌文档不是这样。如果你没有遵循这个,那么你应该在 GAE JDO 问题跟踪器中提出一个问题,向他们展示一个测试用例......但是那里的无主关系是新的,所以谁知道它是否完整
  • 小更新:appengine 中确实出现了问题。我做了一些实验,对于拥有和不拥有的关系,depedent="false/true" 没有效果,无论我做什么,关系总是依赖的。唯一的例外是当我在集合上调用 .clear() 时。对于拥有的关系,它也会删除原始实体,对于非拥有的关系,它不会。

标签: java google-app-engine jdo


【解决方案1】:

我看到了同样的事情。当然我是这一切的新手,但即使有@Unowned 如果我从第一次持久化时所在的 ArrayList 中删除一个项目 对象从数据存储中删除。看起来和我之前添加的差不多 @无主。所以我可以从一个对象的 ArrayList 转移对象的唯一方法 另一个是在调用 remove() 之前先找到它,然后进行深层复制, 然后我可以 remove() 并将副本放在另一个列表中。一点都不自然。

【讨论】:

    【解决方案2】:

    由于我多年来一直在努力解决这个问题,让我分享一下最终对我有用的解决方案。谁知道呢,它可能对其他人有所帮助,因为文档不是很有帮助。

    要从父集合中删除子对象而不删除原始持久对象,您需要:

    1) 使用 Set 而不是 List

    起初我只使用列表,A) 用于排序,B) 因为 Sets + RequestFactory ValueProxy 不起作用。所以一定要使用EntityProxy

    2) 用 @Unowned

    注释这个集合

    他们没有将此注释放在他们的 Unowned 一对多示例中:https://developers.google.com/appengine/docs/java/datastore/jdo/relationships#Unowned_Relationships 但是如果没有它,当您尝试向集合中添加元素时会出现异常(无法更改父级)

    3) 不确定是否有必要,但我也用 @Element(dependent = "false")

    进行了注释

    希望这会帮助一些人。如果没有,那么,没有伤害。

    【讨论】:

    • 谢谢!我无法想象如果我使用 List 或 Set 会有什么不同,但它确实如此。感谢您,我解决了更新父实体导致重复条目的问题,因为它认为子实体不存在,即使它们确实存在。奇怪的是 Google Docs 没有提到 Set 在某些情况下是必须的。失踪的@Unowned 困扰着我,因为我不确定我是否需要它!您是否也知道 SortedSet 是否也有效?再次感谢!
    • 您好,不客气,很高兴能为您提供帮助。 :) 关于 SortedSet,还没有在无主关系中尝试过。我的猜测是它应该可以工作,当然只要你提供一个比较器,但你永远不知道。不过测试应该不会花很长时间。
    【解决方案3】:

    我想这个问题应该得到一个真正的最终答案。

    所描述的行为是由 JDO 中的错误引起的,现在应该已修复。有关详细信息,请参阅http://code.google.com/p/datanucleus-appengine/issues/detail?id=290。另请注意,owned 关系始终 dependent,无论文档怎么说。

    不幸的是,在我移回 JDO 2.0 后,该问题得到了修复。在 JDO 2.0 中,我使用collections of keysforeign keys 实现unowned 关系。实际上这不是一个糟糕的解决方案,所以我不打算再次尝试 JDO 3.0。对于键的集合,我使用batch fetch 来获取子对象,如果是外键,我使用带有where 语句的简单查询。有时最好使用第一种解决方案,有时使用第二种解决方案。无论如何,这一切都被一个干净的 API 所覆盖,因此最终的代码简单而“自然”。 (我希望在文档中直接描述这种方法,这样我们就不必费力地学习它了。)

    重要的是,在这两种情况下,我都可以在不删除原始实体的情况下破坏关系。这是真正的unowned 关系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多